<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/favicon.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon.png">
  <link rel="mask-icon" href="/images/favicon.png" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css">
  <link rel="stylesheet" href="//cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.css">


<script id="hexo-configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    hostname: new URL('https://codz-me.vercel.app').hostname,
    root: '/',
    scheme: 'Muse',
    version: '7.7.1',
    exturl: false,
    sidebar: {"position":"right","display":"post","padding":18,"offset":12,"onmobile":false},
    copycode: {"enable":false,"show_result":false,"style":null},
    back2top: {"enable":true,"sidebar":false,"scrollpercent":false},
    bookmark: {"enable":false,"color":"#222","save":"auto"},
    fancybox: true,
    mediumzoom: false,
    lazyload: false,
    pangu: false,
    comments: {"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},
    algolia: {
      appID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    },
    localsearch: {"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},
    path: '',
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}
  };
</script>

  <meta name="description" content="Bug Not Found">
<meta property="og:type" content="website">
<meta property="og:title" content="Code Is Poetry">
<meta property="og:url" content="https://codz-me.vercel.app/page/5/index.html">
<meta property="og:site_name" content="Code Is Poetry">
<meta property="og:description" content="Bug Not Found">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="laudukang">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="https://codz-me.vercel.app/page/5/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome: true,
    isPost: false
  };
</script>

  <title>Code Is Poetry</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-meta">

    <div>
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">Code Is Poetry</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
  </div>

  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>
</div>


<nav class="site-nav">
  
  <ul id="menu" class="menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-fw fa-home"></i>首页</a>

  </li>
        <li class="menu-item menu-item-about">

    <a href="/about/" rel="section"><i class="fa fa-fw fa-user"></i>关于</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-fw fa-tags"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-fw fa-th"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-fw fa-archive"></i>归档</a>

  </li>
        <li class="menu-item menu-item-commonweal">

    <a href="/404/" rel="section"><i class="fa fa-fw fa-heartbeat"></i>公益 404</a>

  </li>
  </ul>

</nav>
</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>
  <div class="reading-progress-bar"></div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content">
            

  <div class="posts-expand">
        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://codz-me.vercel.app/2015/07/20/java-post-validation-code/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/head.png">
      <meta itemprop="name" content="laudukang">
      <meta itemprop="description" content="Bug Not Found">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Code Is Poetry">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2015/07/20/java-post-validation-code/" class="post-title-link" itemprop="url">Java 实现图形验证码</a>
        </h1>

        <div class="post-meta">
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2015-07-20 00:38:26 00:38:26" itemprop="dateModified" datetime="2015-07-20T00:38:26+08:00">2015-07-20 00:38:26</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Java/" itemprop="url" rel="index">
                    <span itemprop="name">Java</span>
                  </a>
                </span>
            </span>

          
            <span id="/2015/07/20/java-post-validation-code/" class="post-meta-item leancloud_visitors" data-flag-title="Java 实现图形验证码" title="阅读次数">
                <span hidden class="leancloud-visitors-count"></span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>实现图形验证码大致分为5步上来完成：</p>
<ol>
<li>建立图形缓冲区；</li>
<li>在图形缓冲区用随机颜色填充背景。</li>
<li>在图形缓冲区上输出验证码。</li>
<li>将验证码保存在HttpSession对象中。</li>
<li>向客户端输出图形验证码。</li>
</ol>
<p>通过 ValidationCode 类来实现验证码功能，该类也是Servlet类，在客户端只要像访问普通Servlet一样访问ValidationCode类即可。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.cnblogs.jbelial.Validation;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.awt.*;</span><br><span class="line"><span class="keyword">import</span> java.awt.image.BufferedImage;</span><br><span class="line"><span class="keyword">import</span> java.io.* ;</span><br><span class="line"><span class="keyword">import</span> java.util.Random;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.imageio.ImageIO;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServlet;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletRequest;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletResponse;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpSession;</span><br><span class="line"></span><br><span class="line"><span class="meta">@SuppressWarnings</span>(<span class="string">"serial"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ValidationCode</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line"><span class="comment">//    图形验证码的字符集合，系统通过随机从这些字符串中选择一些字符作为验证码</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> String codeChars =</span><br><span class="line">        <span class="string">"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTYVWXYZ"</span> ;</span><br><span class="line"><span class="comment">//    返回一个随机颜色</span></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">static</span> Color <span class="title">getRandomColor</span><span class="params">(<span class="keyword">int</span> minColor , <span class="keyword">int</span> maxColor)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        Random random = <span class="keyword">new</span> Random() ;</span><br><span class="line">        <span class="keyword">if</span> (minColor &gt; <span class="number">255</span>)</span><br><span class="line">            minColor = <span class="number">255</span> ;</span><br><span class="line">        <span class="keyword">if</span> (maxColor &gt; <span class="number">255</span>)</span><br><span class="line">            maxColor = <span class="number">255</span> ;</span><br><span class="line"><span class="comment">//        获取颜色的随机值</span></span><br><span class="line">        <span class="keyword">int</span> red = minColor + random.nextInt(maxColor - minColor) ;</span><br><span class="line">        <span class="keyword">int</span> green = minColor + random.nextInt(maxColor - minColor) ;</span><br><span class="line">        <span class="keyword">int</span> blue = minColor + random.nextInt(maxColor - minColor) ;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> Color(red,green,blue) ;  </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doGet</span> <span class="params">(HttpServletRequest request ,</span></span></span><br><span class="line"><span class="function"><span class="params">            HttpServletResponse response)</span> <span class="keyword">throws</span> IOException</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//       获取验证码集合的长度。</span></span><br><span class="line">        <span class="keyword">int</span> charsLength = codeChars.length() ;</span><br><span class="line"><span class="comment">//        关闭浏览器缓冲区</span></span><br><span class="line">        response.setHeader(<span class="string">"ragma"</span>, <span class="string">"No-cache"</span>) ;</span><br><span class="line">        response.setHeader(<span class="string">"Cache-Control"</span>, <span class="string">"no-cache"</span>) ;</span><br><span class="line">        response.setDateHeader(<span class="string">"Expires"</span>, <span class="number">0</span>) ;</span><br><span class="line"><span class="comment">//        设置图片传送的格式。</span></span><br><span class="line">        response.setContentType(<span class="string">"image/jpeg"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//        设置图形验证码的长和宽度</span></span><br><span class="line">        <span class="keyword">int</span> width = <span class="number">90</span> ;</span><br><span class="line">        <span class="keyword">int</span> height = <span class="number">20</span> ;</span><br><span class="line"><span class="comment">//        建立图形缓冲区</span></span><br><span class="line">        BufferedImage image = <span class="keyword">new</span> BufferedImage(width , height,</span><br><span class="line">                BufferedImage.TYPE_INT_RGB) ;</span><br><span class="line"><span class="comment">//        获取用于输出文字的Graphics对象</span></span><br><span class="line">        Graphics graphics = image.getGraphics() ;</span><br><span class="line"></span><br><span class="line">        Random random = <span class="keyword">new</span> Random() ;</span><br><span class="line"></span><br><span class="line"><span class="comment">//        设置要填充的颜色</span></span><br><span class="line">        graphics.setColor(getRandomColor(<span class="number">180</span> , <span class="number">250</span>)) ;</span><br><span class="line"><span class="comment">//        填充图形背景</span></span><br><span class="line">        graphics.fillRect(<span class="number">0</span>, <span class="number">0</span>, width, height) ;</span><br><span class="line"><span class="comment">//        设置初始字体和颜色</span></span><br><span class="line">        graphics.setFont(<span class="keyword">new</span> Font(<span class="string">"Time New Roman"</span> , Font.ITALIC, height)) ;</span><br><span class="line">        graphics.setColor(getRandomColor(<span class="number">120</span>,<span class="number">180</span>)) ;</span><br><span class="line"></span><br><span class="line"><span class="comment">//        保存验证码</span></span><br><span class="line">        StringBuilder validationCode = <span class="keyword">new</span> StringBuilder() ;</span><br><span class="line"><span class="comment">//        验证码的随机字体</span></span><br><span class="line">        String[] fontNames = &#123;<span class="string">"Times New Roman"</span> , <span class="string">"Book antiqua"</span> , <span class="string">"Arial"</span> &#125; ;</span><br><span class="line"><span class="comment">//        随机生成验证码</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span> ; i &lt; <span class="number">4</span> ; ++ i)</span><br><span class="line">        &#123;</span><br><span class="line"><span class="comment">//            设置当前验证码字符的字体</span></span><br><span class="line">            graphics.setFont(<span class="keyword">new</span> Font(fontNames[random.nextInt(<span class="number">3</span>)] , Font.ITALIC ,</span><br><span class="line">                    height)) ;</span><br><span class="line"><span class="comment">//            随机获得验证码的字符</span></span><br><span class="line">            <span class="keyword">char</span> codeChar = codeChars.charAt(random.nextInt(charsLength)) ;</span><br><span class="line">            validationCode.append(codeChar) ;</span><br><span class="line">            graphics.setColor(getRandomColor(<span class="number">20</span>,<span class="number">120</span>)) ;</span><br><span class="line"><span class="comment">//            在图形上输出验证码字符</span></span><br><span class="line">            graphics.drawString(String.valueOf(codeChar), <span class="number">16</span>*i+random.nextInt(<span class="number">7</span>),</span><br><span class="line">                    height - random.nextInt(<span class="number">6</span>) ) ;</span><br><span class="line">        &#125;</span><br><span class="line"><span class="comment">//        获得Session对象，并设置Session对象为3分钟</span></span><br><span class="line">        HttpSession session = request.getSession();</span><br><span class="line">        session.setMaxInactiveInterval(<span class="number">5</span>*<span class="number">60</span>) ;</span><br><span class="line"><span class="comment">//        将验证码放入session对象中.</span></span><br><span class="line">        session.setAttribute(<span class="string">"validationCode"</span>,validationCode.toString() ) ;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//        关闭graphics对象。</span></span><br><span class="line">        graphics.dispose() ;  </span><br><span class="line"><span class="comment">//        向客户端发送图形验证码</span></span><br><span class="line">        ImageIO.write(image,<span class="string">"JPEG"</span> ,response.getOutputStream()) ;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doPost</span> <span class="params">(HttpServletRequest request ,</span></span></span><br><span class="line"><span class="function"><span class="params">            HttpServletResponse response)</span> <span class="keyword">throws</span> IOException</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">            doGet(request , response) ;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<img src="/2015/07/20/java-post-validation-code/java-validation-code.png" alt="java validation code example" title="java validation code example">

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://codz-me.vercel.app/2015/07/19/tomcat-log-user-ip/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/head.png">
      <meta itemprop="name" content="laudukang">
      <meta itemprop="description" content="Bug Not Found">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Code Is Poetry">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2015/07/19/tomcat-log-user-ip/" class="post-title-link" itemprop="url">Tomcat Log 记录访问者 ip 及访问地址</a>
        </h1>

        <div class="post-meta">
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2015-08-14 16:58:07 16:58:07" itemprop="dateModified" datetime="2015-08-14T16:58:07+08:00">2015-08-14 16:58:07</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Web/" itemprop="url" rel="index">
                    <span itemprop="name">Web</span>
                  </a>
                </span>
            </span>

          
            <span id="/2015/07/19/tomcat-log-user-ip/" class="post-meta-item leancloud_visitors" data-flag-title="Tomcat Log 记录访问者 ip 及访问地址" title="阅读次数">
                <span hidden class="leancloud-visitors-count"></span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>在tomcat目录<code>server.xml</code>里面加入</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;valve <span class="attribute">classname</span>=<span class="string">"org.apache.catalina.valves.AccessLogValve"</span> <span class="attribute">directory</span>=<span class="string">"logs"</span> <span class="attribute">prefix</span>=<span class="string">"localhost_access_log."</span> <span class="attribute">suffix</span>=<span class="string">".txt"</span> <span class="attribute">pattern</span>=<span class="string">"common"</span> <span class="attribute">resolvehosts</span>=<span class="string">"false"</span>&gt;&lt;/valve&gt;</span><br></pre></td></tr></table></figure>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://codz-me.vercel.app/2015/07/18/server-distinct-ajax-request-whether-sync-or-async/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/head.png">
      <meta itemprop="name" content="laudukang">
      <meta itemprop="description" content="Bug Not Found">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Code Is Poetry">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2015/07/18/server-distinct-ajax-request-whether-sync-or-async/" class="post-title-link" itemprop="url">Server distinct ajax request whether sync or async</a>
        </h1>

        <div class="post-meta">
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2015-07-18 16:48:01 16:48:01" itemprop="dateModified" datetime="2015-07-18T16:48:01+08:00">2015-07-18 16:48:01</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Web/" itemprop="url" rel="index">
                    <span itemprop="name">Web</span>
                  </a>
                </span>
            </span>

          
            <span id="/2015/07/18/server-distinct-ajax-request-whether-sync-or-async/" class="post-meta-item leancloud_visitors" data-flag-title="Server distinct ajax request whether sync or async" title="阅读次数">
                <span hidden class="leancloud-visitors-count"></span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>两种请求在请求的Header不同，Ajax 异步请求比传统的同步请求多了一个头参数</p>
<ol>
<li><p>传统同步请求参数</p>
<figure class="highlight angelscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">accept text/html,application/xhtml+xml,application/xml;q=<span class="number">0.9</span>,/;q=<span class="number">0.8</span></span><br><span class="line">accept-charset gb2312,utf<span class="number">-8</span>;q=<span class="number">0.7</span>,*;q=<span class="number">0.7</span></span><br><span class="line">accept-encoding gzip,deflate</span><br><span class="line">accept-language zh-cn,zh;q=<span class="number">0.5</span></span><br><span class="line">cache-control max-age=<span class="number">0</span></span><br><span class="line">connection keep-alive</span><br><span class="line">cookie JSESSIONID=<span class="number">1</span>A3BED3F593EA9747C9FDA16D309AF6B</span><br><span class="line">host <span class="number">192.168</span><span class="number">.101</span><span class="number">.72</span>:<span class="number">8080</span></span><br><span class="line">keep-alive <span class="number">300</span></span><br><span class="line"><span class="built_in">ref</span>erer http:<span class="comment">//192.168.101.72:8080/htfsweb/spring_security_login</span></span><br><span class="line">user-agent Mozilla/<span class="number">5.0</span> (Windows; U; Windows NT <span class="number">5.1</span>; zh-CN; rv:<span class="number">1.9</span><span class="number">.0</span><span class="number">.15</span>) Gecko/<span class="number">2009101601</span> Firefox/<span class="number">3.0</span><span class="number">.15</span> (.NET CLR <span class="number">3.5</span><span class="number">.30729</span>)</span><br></pre></td></tr></table></figure>
</li>
<li><p>Ajax 异步请求方式</p>
<figure class="highlight angelscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">accept /</span><br><span class="line">accept-language zh-cn</span><br><span class="line"><span class="built_in">ref</span>erer http:<span class="comment">//192.168.101.72:8080/scm/?token=3b194bff23bf6acecea5661ac8e14c51</span></span><br><span class="line">x-requested-with XMLHttpRequest</span><br><span class="line">content-type application/x-www-form-urlencoded,text/javascript</span><br><span class="line">accept-encoding gzip, deflate</span><br><span class="line">user-agent Mozilla/<span class="number">4.0</span> (compatible; MSIE <span class="number">7.0</span>; Windows NT <span class="number">5.1</span>; Trident/<span class="number">4.0</span>; QQDownload <span class="number">598</span>; .NET CLR <span class="number">2.0</span><span class="number">.50727</span>; .NET CLR <span class="number">3.0</span><span class="number">.04506</span><span class="number">.648</span>; .NET CLR <span class="number">3.5</span><span class="number">.21022</span>; CIBA; .NET CLR <span class="number">1.1</span><span class="number">.4322</span>; .NET CLR <span class="number">3.0</span><span class="number">.4506</span><span class="number">.2152</span>; .NET CLR <span class="number">3.5</span><span class="number">.30729</span>; InfoPath<span class="number">.1</span>)</span><br><span class="line">host <span class="number">192.168</span><span class="number">.101</span><span class="number">.72</span>:<span class="number">8080</span></span><br><span class="line">content-length <span class="number">233</span></span><br><span class="line">connection Keep-Alive</span><br><span class="line">cache-control no-cache</span><br><span class="line">cookie CSS=undefined; JSESSIONID=<span class="number">1</span>B9AC25036290F7FB6823CCE1A24E541</span><br></pre></td></tr></table></figure>

</li>
</ol>
<p>可以看到 Ajax 请求多了个 <code>x-requested-with</code> ，可以利用它，<code>request.getHeader(&quot;x-requested-with&quot;);</code> 为 null，则为传统同步请求，为 XMLHttpRequest，则为 Ajax 异步请求。</p>
<p>下面是Struts拦截器示例代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">intercept</span><span class="params">(ActionInvocation invocation)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line"></span><br><span class="line">    ActionContext ctx = invocation.getInvocationContext();</span><br><span class="line">    Map session = ctx.getSession();</span><br><span class="line">    User user = (User) session.get(Constants.SESSION_USER_KEY);</span><br><span class="line">    <span class="keyword">if</span> (user == <span class="keyword">null</span>) &#123;</span><br><span class="line">        HttpServletRequest request = ServletActionContext.getRequest();</span><br><span class="line">        HttpServletResponse response = ServletActionContext.getResponse();</span><br><span class="line">        PrintWriter pw = response.getWriter();</span><br><span class="line">        String flag = <span class="string">""</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 对ajax请求的拦截</span></span><br><span class="line">        <span class="keyword">if</span> (request.getHeader(<span class="string">"X-Requested-With"</span>) != <span class="keyword">null</span></span><br><span class="line">                &amp;&amp; request.getHeader(<span class="string">"X-Requested-With"</span>).equalsIgnoreCase(</span><br><span class="line">                        <span class="string">"XMLHttpRequest"</span>)) &#123;</span><br><span class="line">            response.setCharacterEncoding(<span class="string">"text/html;charset=utf-8"</span>);</span><br><span class="line">            response.setContentType(<span class="string">"text/html;charset=utf-8"</span>);</span><br><span class="line">            flag = <span class="string">"9999"</span>;</span><br><span class="line">            pw.write(flag);</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 不是异步请求的拦截</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            response.setCharacterEncoding(<span class="string">"text/html;charset=utf-8"</span>);</span><br><span class="line">            response.sendRedirect(<span class="string">"/businessTest/login.jsp"</span>);</span><br><span class="line">            <span class="keyword">return</span> <span class="string">"login"</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> invocation.invoke();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://codz-me.vercel.app/2015/07/17/setup-linux-server/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/head.png">
      <meta itemprop="name" content="laudukang">
      <meta itemprop="description" content="Bug Not Found">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Code Is Poetry">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2015/07/17/setup-linux-server/" class="post-title-link" itemprop="url">[转]Linux 服务器的初步配置流程</a>
        </h1>

        <div class="post-meta">
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2015-07-17 01:19:20 01:19:20" itemprop="dateModified" datetime="2015-07-17T01:19:20+08:00">2015-07-17 01:19:20</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Linux/" itemprop="url" rel="index">
                    <span itemprop="name">Linux</span>
                  </a>
                </span>
            </span>

          
            <span id="/2015/07/17/setup-linux-server/" class="post-meta-item leancloud_visitors" data-flag-title="[转]Linux 服务器的初步配置流程" title="阅读次数">
                <span hidden class="leancloud-visitors-count"></span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>开发网站的时候，常常需要自己配置Linux服务器。<br>本文记录配置Linux服务器的初步流程，也就是系统安装完成后，下一步要做的事情。这主要是我自己的总结和备忘，如果有遗漏，欢迎大家补充。<br>下面的操作针对Debian/Ubuntu系统，其他Linux系统也类似，就是部分命令稍有不同。</p>
<p><img src="http://image.beekka.com/blog/2014/bg2014031401.jpg" alt="server"></p>
<p>第一步：root用户登录<br>首先，使用root用户登录远程主机（假定IP地址是128.199.209.242）。</p>
<figure class="highlight angelscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh <span class="symbol">root@</span><span class="number">128.199</span><span class="number">.209</span><span class="number">.242</span></span><br></pre></td></tr></table></figure>
<p>这时，命令行会出现警告，表示这是一个新的地址，存在安全风险。键入yes，表示接受。然后，就应该可以顺利登入远程主机。<br>接着，修改root用户的密码。</p>
<figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">passwd</span></span><br></pre></td></tr></table></figure>
<p>第二步：新建用户<br>首先，添加一个用户组（这里假定为admin用户组）。</p>
<figure class="highlight armasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">addgroup </span>admin</span><br></pre></td></tr></table></figure>
<p>然后，添加一个新用户（假定为bill）。</p>
<figure class="highlight armasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">useradd</span> -d /home/<span class="keyword">bill </span>-s /<span class="keyword">bin/bash </span>-m <span class="keyword">bill</span></span><br></pre></td></tr></table></figure>
<p>上面命令中，参数d指定用户的主目录，参数s指定用户的shell，参数m表示如果该目录不存在，则创建该目录。<br>接着，设置新用户的密码。</p>
<figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">passwd bill</span></span><br></pre></td></tr></table></figure>
<p>将新用户（bill）添加到用户组（admin）。</p>
<figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">usermod -a -G admin bill</span></span><br></pre></td></tr></table></figure>
<p>接着，为新用户设定sudo权限。</p>
<figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">visudo</span></span><br></pre></td></tr></table></figure>
<p>visudo命令会打开sudo设置文件/etc/sudoers，找到下面这一行。</p>
<figure class="highlight ada"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">root    <span class="keyword">ALL</span>=(<span class="keyword">ALL</span>:<span class="keyword">ALL</span>) <span class="keyword">ALL</span></span><br></pre></td></tr></table></figure>
<p>在这一行的下面，再添加一行。</p>
<figure class="highlight ada"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">root    <span class="keyword">ALL</span>=(<span class="keyword">ALL</span>:<span class="keyword">ALL</span>) <span class="keyword">ALL</span></span><br><span class="line">bill    <span class="keyword">ALL</span>=(<span class="keyword">ALL</span>) NOPASSWD: <span class="keyword">ALL</span></span><br></pre></td></tr></table></figure>
<p>上面的NOPASSWD表示，切换sudo的时候，不需要输入密码，我喜欢这样比较省事。如果出于安全考虑，也可以强制要求输入密码。</p>
<figure class="highlight ada"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">root    <span class="keyword">ALL</span>=(<span class="keyword">ALL</span>:<span class="keyword">ALL</span>) <span class="keyword">ALL</span></span><br><span class="line">bill    <span class="keyword">ALL</span>=(<span class="keyword">ALL</span>:<span class="keyword">ALL</span>) <span class="keyword">ALL</span></span><br></pre></td></tr></table></figure>
<p>然后，先退出root用户的登录，再用新用户的身份登录，检查到这一步为止，是否一切正常。</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">exit</span></span><br><span class="line">ssh bill@<span class="number">128.199</span>.<span class="number">209.242</span></span><br></pre></td></tr></table></figure>
<p>第三步：SSH设置<br>首先，确定本机有SSH公钥（一般是文件~/.ssh/id_rsa.pub），如果没有的话，使用ssh-keygen命令生成一个（可参考我写的SSH教程）。<br>在本机上另开一个shell窗口，将本机的公钥拷贝到服务器的authorized_keys文件。</p>
<figure class="highlight jboss-cli"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">cat ~<span class="string">/.ssh/id_rsa.pub</span> | ssh bill@128.199.209.242 'mkdir -p <span class="string">.ssh</span> &amp;&amp; cat - &gt;&gt; ~<span class="string">/.ssh/authorized_keys</span>'</span><br><span class="line"></span><br><span class="line"><span class="comment"># 或者在服务器端，运行下面命令</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">echo</span> <span class="string">"ssh-rsa [your public key]"</span> &gt; ~<span class="string">/.ssh/authorized_keys</span></span><br></pre></td></tr></table></figure>
<p>然后，进入服务器，编辑SSH配置文件/etc/ssh/sshd_config。</p>
<figure class="highlight dts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo cp <span class="meta-keyword">/etc/</span>ssh/sshd_config ~</span><br><span class="line">sudo nano <span class="meta-keyword">/etc/</span>ssh/sshd_config</span><br></pre></td></tr></table></figure>
<p>在配置文件中，将SSH的默认端口22改掉，可以改成从1025到65536之间的任意一个整数（这里假定为25000）。</p>
<figure class="highlight angelscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Port <span class="number">25000</span></span><br></pre></td></tr></table></figure>
<p>然后，检查几个设置是否设成下面这样，确保去除前面的#号。</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">Protocol</span> <span class="number">2</span></span><br><span class="line"></span><br><span class="line"><span class="string">PermitRootLogin</span> <span class="literal">no</span></span><br><span class="line"><span class="string">PermitEmptyPasswords</span> <span class="literal">no</span></span><br><span class="line"><span class="string">PasswordAuthentication</span> <span class="literal">no</span></span><br><span class="line"></span><br><span class="line"><span class="string">RSAAuthentication</span> <span class="literal">yes</span></span><br><span class="line"><span class="string">PubkeyAuthentication</span> <span class="literal">yes</span></span><br><span class="line"><span class="string">AuthorizedKeysFile</span> <span class="string">.ssh/authorized_keys</span></span><br><span class="line"></span><br><span class="line"><span class="string">UseDNS</span> <span class="literal">no</span></span><br></pre></td></tr></table></figure>
<p>上面主要是禁止root用户登录，以及禁止用密码方式登录。<br>接着，在配置文件的末尾，指定允许登陆的用户。</p>
<figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">AllowUsers bill</span></span><br></pre></td></tr></table></figure>
<p>保存后，退出文件编辑。<br>接着，改变authorized_keys文件的权限。</p>
<figure class="highlight angelscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo chmod <span class="number">600</span> ~/.ssh/authorized_keys &amp;&amp; chmod <span class="number">700</span> ~/.ssh/</span><br></pre></td></tr></table></figure>
<p>然后，重启SSHD。</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">sudo<span class="built_in"> service </span>ssh restart</span><br><span class="line"></span><br><span class="line"><span class="comment"># 或者</span></span><br><span class="line"></span><br><span class="line">sudo /etc/init.d/ssh restart</span><br></pre></td></tr></table></figure>
<p>下面的一步是可选的。在本机~/.ssh文件夹下创建config文件，内容如下。</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Host s1</span><br><span class="line">HostName 128.199.209.242</span><br><span class="line">User bill</span><br><span class="line">Port 25000</span><br></pre></td></tr></table></figure>
<p>最后，在本机另开一个shell窗口，测试SSH能否顺利登录。</p>
<figure class="highlight armasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">ssh</span> <span class="built_in">s1</span></span><br></pre></td></tr></table></figure>
<p>第四步：运行环境配置<br>首先，检查服务器的区域设置。</p>
<figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">locale</span></span><br></pre></td></tr></table></figure>
<p>如果结果不是en_US.UTF-8，建议都设成它。</p>
<figure class="highlight angelscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo locale-gen en_US en_US.UTF<span class="number">-8</span> en_CA.UTF<span class="number">-8</span></span><br><span class="line">sudo dpkg-reconfigure locales</span><br></pre></td></tr></table></figure>
<p>然后，更新软件。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get update</span><br><span class="line">sudo apt-get upgrade</span><br></pre></td></tr></table></figure>
<p>最后，再根据需要，做一些安全设置，比如搭建防火墙，关闭HTTP、HTTPs、SSH以外的端口，再比如安装Fail2Ban，详细可参考这篇《Securing a Linux Server》。<br>（完）</p>
<p>reference:</p>
<ul>
<li><a href="http://www.ruanyifeng.com/blog/2014/03/server_setup.html" target="_blank" rel="noopener">Linux服务器的初步配置流程</a></li>
</ul>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://codz-me.vercel.app/2015/07/11/rich-text-editor-plus/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/head.png">
      <meta itemprop="name" content="laudukang">
      <meta itemprop="description" content="Bug Not Found">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Code Is Poetry">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2015/07/11/rich-text-editor-plus/" class="post-title-link" itemprop="url">Rich Text Editor Plus</a>
        </h1>

        <div class="post-meta">
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2015-07-12 12:17:03 12:17:03" itemprop="dateModified" datetime="2015-07-12T12:17:03+08:00">2015-07-12 12:17:03</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Git/" itemprop="url" rel="index">
                    <span itemprop="name">Git</span>
                  </a>
                </span>
            </span>

          
            <span id="/2015/07/11/rich-text-editor-plus/" class="post-meta-item leancloud_visitors" data-flag-title="Rich Text Editor Plus" title="阅读次数">
                <span hidden class="leancloud-visitors-count"></span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <h1 id="Rich-Text-Editor-Plus"><a href="#Rich-Text-Editor-Plus" class="headerlink" title="Rich Text Editor Plus"></a>Rich Text Editor Plus</h1><p>A collection of editor with customized update, <a href="https://github.com/laudukang/rich-text-editor-plus" target="_blank" rel="noopener">Rich Text Editor Plus Github</a></p>
<h2 id="Ueditor-Change-Log"><a href="#Ueditor-Change-Log" class="headerlink" title="Ueditor Change Log"></a>Ueditor Change Log</h2><ol>
<li><p>表情文件本地化<br> images目录下的所有表情文件夹复制到<code>dialogs/emotion/images/</code>文件夹下面，修改<code>editor_config.js</code>文件，去掉<code>emotionLocalization</code>项的注释，值改为<code>true</code>。</p>
</li>
<li><p>列表文件本地化<br> 解压放到你的<code>themes/</code>文件夹下（可以按照需求放置路径），修改<code>editor_config.js</code>文件，修改listiconpath配置项：</p>
<figure class="highlight ada"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">//如果是自己的目录，请使用  <span class="string">'/'</span>开头的绝对路径</span><br><span class="line">listiconpath : <span class="type">URL</span>+<span class="symbol">'themes</span>/ueditor-list/'</span><br></pre></td></tr></table></figure>
<p>在发布文章的页面，引用<code>uparse.js</code>，并运行 uParse 函数，传入列表路径：</p>
 <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;script type=<span class="string">"text/javascript"</span>&gt;</span><br><span class="line">uParse(<span class="string">'.content'</span>,&#123;</span><br><span class="line">    <span class="string">'liiconpath'</span>:<span class="string">'/UTest/ueditor/themes/ueditor-list/'</span>    <span class="comment">//使用 '/' 开头的绝对路径</span></span><br><span class="line">&#125;)</span><br><span class="line">&lt;<span class="regexp">/script&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>升级ueditor的SyntaxHighlighter，ueditor默认使用了SyntaxHighlighter的Default主题</p>
<p> 更多配置请参见<br> <a href="http://www.crarun.com/article-3.html" target="_blank" rel="noopener">升级UEditor的SyntaxHighlighter</a></p>
</li>
<li><p>更改了ueditor的默认上传位置，使用了tomcat的虚拟路径，避免重新部署后丢失先前的文件，</p>
<p> 这里修改了<code>com.baidu.ueditor.ConfigManager</code>类，主要是对<code>ueditor.config.js</code>虚拟路径配置的处理;</p>
<p> 还修改了<code>com.baidu.ueditor.hunter.FileManager</code>和<code>com.baidu.ueditor.upload.BinaryUploader</code>，主要是对配置了tomcat虚拟路径后的处理;</p>
<p> 特别地，修改了原图片在线管理/文件在线附件的获取，原ueditor可以获取文件的个数并显示出来，但图片/文件显示不了，因为其封装的路径有文件，原ueditor的封装使用了绝对路径，即把</p>
 <figure class="highlight taggerscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">D:<span class="symbol">\T</span>omcat 7.0.57<span class="symbol">\w</span>ebapps<span class="symbol">\E</span>ditorDemo<span class="symbol">\u</span>pload<span class="symbol">\i</span>mage<span class="symbol">\2</span>0150711<span class="symbol">\1</span>436591786822080766.jpg</span><br></pre></td></tr></table></figure>
<p> 这样的文件路径返回前台，这样子前台ueditor是获取不了文件的，所以改成了相对路径，见FileManager类下的getPath (File)方法；</p>
<p> 关于tomcat虚拟路径的配置，修改tomcat conf目录下的server.xml，在Host里面添加:</p>
 <figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;Context <span class="attribute">path</span>=<span class="string">"/EditorDemo/ueditorupload"</span> <span class="attribute">docBase</span>=<span class="string">"D:\apache\EditorDemo\ueditor\ueditorupload"</span>/&gt;</span><br></pre></td></tr></table></figure>
<p> 这部分内容参考了<br> <a href="http://blog.csdn.net/will_awoke/article/details/39579061" target="_blank" rel="noopener">百度UEditor 上传组件 使用虚拟路径映射配置</a></p>
</li>
<li><p>是否保存上传文件到虚拟路径的配置请参见<code>ueditor/jsp/</code>下的<code>config.json</code>，xxxRealMappingPath指定了物理路径的位置</p>
</li>
<li><p>修改百度map组件的默认位置为<code>广东广州</code></p>
</li>
<li><p>该版本基于ubuilder_1_4_3-utf8-jsp修改</p>
</li>
<li><p>ueditor这部分的最后修改时间2015年7月11日22:31:04</p>
</li>
</ol>
<h2 id="Kindeditor-Change-Log"><a href="#Kindeditor-Change-Log" class="headerlink" title="Kindeditor Change Log"></a>Kindeditor Change Log</h2><ol>
<li>基于kindeditor-4.1.10修改</li>
<li>修改代码高亮为SyntaxHighlighter插件</li>
<li>添加插入附件的文件类型图标，用于插入附件后在前面显示</li>
<li>修改了<code>kindeditor/jsp</code>文件夹下的<code>file_manager_json.jsp</code>和<code>upload_json.jsp</code>文件，用于上传文件/文件管理器的支持</li>
<li>添加/修改了jwplayer插件，用于播放流媒体文件</li>
<li>虚拟路径 <figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;Context <span class="attribute">path</span>=<span class="string">"/EditorDemo/kindeditorupload"</span> <span class="attribute">docBase</span>=<span class="string">"D:\apache\EditorDemo\kindeditor\kindeditorupload"</span>/&gt;</span><br></pre></td></tr></table></figure></li>
<li>kindeditor这部分的最后修改时间2015年7月12日01:30:29</li>
</ol>
<h2 id="Ckeditor-Change-Log"><a href="#Ckeditor-Change-Log" class="headerlink" title="Ckeditor Change Log"></a>Ckeditor Change Log</h2><ol>
<li><p>基于ckeditor_4.5.1_full修改</p>
</li>
<li><p>添加了<code>jsp/browse.jsp</code>和<code>jsp/upload.jsp</code>两个文件，分别用于浏览服务器文件和上传图片/附件到服务器；</p>
<p> <code>config.js</code>配置了这两个文件的调用；</p>
<p> 修改返回路径为服务器相对路径saveUrl；</p>
<p> 修改上传文件新文件名为当前日期+随机码，tomcat需要配置虚拟路径</p>
 <figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;Context <span class="attribute">path</span>=<span class="string">"/EditorDemo/ckeditorupload"</span> <span class="attribute">docBase</span>=<span class="string">"D:\apache\EditorDemo\ckeditor\ckeditorupload"</span>/&gt;</span><br></pre></td></tr></table></figure>
</li>
<li><p>ckeditor这部分的最后修改时间2015年7月12日12:11:55</p>
</li>
</ol>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://codz-me.vercel.app/2015/07/10/java-forkjoin/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/head.png">
      <meta itemprop="name" content="laudukang">
      <meta itemprop="description" content="Bug Not Found">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Code Is Poetry">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2015/07/10/java-forkjoin/" class="post-title-link" itemprop="url">JAVA 并行框架 ForkJoin</a>
        </h1>

        <div class="post-meta">
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2015-07-18 17:13:01 17:13:01" itemprop="dateModified" datetime="2015-07-18T17:13:01+08:00">2015-07-18 17:13:01</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Java/" itemprop="url" rel="index">
                    <span itemprop="name">Java</span>
                  </a>
                </span>
            </span>

          
            <span id="/2015/07/10/java-forkjoin/" class="post-meta-item leancloud_visitors" data-flag-title="JAVA 并行框架 ForkJoin" title="阅读次数">
                <span hidden class="leancloud-visitors-count"></span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>ForkJoin是Java7提供的原生多线程并行处理框架，其基本思想是将大人物分割成小任务，最后将小任务聚合起来得到结果。</p>
<p>它非常类似于HADOOP提供的MapReduce框架，只是MapReduce的任务可以针对集群内的所有计算节点，可以充分利用集群的能力完成计算任务。</p>
<p>ForkJoin更加类似于单机版的MapReduce。</p>
<p>即使不通过mapreduce，仅有应用程序本身进行任务的分解与合成也是可以的，但从实现难度上考虑，自己实现可能会带来较大规模的复杂度，因此程序员急需一种范式来处理这一类的任务。</p>
<p>在处理多线程中已经有了如AKKA这样的基于ACTOR模型的框架，而FORKJOIN则是针对具有明显可以进行任务分割特性需求的实现。</p>
<p>其场景为：如果一个应用程序能够被分解成多个子任务，而且结合多个子任务的结果就能够得到最终的答案，那么它就适合使用FORK/JOIN模式来实现。</p>
<img src="/2015/07/10/java-forkjoin/501882267.jpg" alt="501882267.jpg" title="">

<p>Fork/Join使用两个类完成以上两件事情：</p>
<ul>
<li><p>ForkJoinTask: 我们要使用ForkJoin框架，必须首先创建一个ForkJoin任务。它提供在任务中执行fork()和join的操作机制，通常我们不直接继承ForkjoinTask类，只需要直接继承其子类。</p>
<ul>
<li>RecursiveAction，用于没有返回结果的任务</li>
<li>RecursiveTask，用于有返回值的任务</li>
</ul>
</li>
<li><p>ForkJoinPool：task要通过ForkJoinPool来执行，分割的子任务也会添加到当前工作线程的双端队列中，进入队列的头部。<br>当一个工作线程中没有任务时，会从其他工作线程的队列尾部获取一个任务。<br>ForkJoin框架使用了工作窃取的思想（work-stealing），算法从其他队列中窃取任务来执行，其工作流图为：</p>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.inspur.jiyq.forkjoin.sum;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.ForkJoinPool;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.Future;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.RecursiveTask;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CountTask</span> <span class="keyword">extends</span> <span class="title">RecursiveTask</span>&lt;<span class="title">Integer</span>&gt;</span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">long</span> serialVersionUID = -<span class="number">3611254198265061729L</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> threshold = <span class="number">2</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> start;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> end;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">CountTask</span><span class="params">(<span class="keyword">int</span> start, <span class="keyword">int</span> end)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.start = start;</span><br><span class="line">        <span class="keyword">this</span>.end = end;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> Integer <span class="title">compute</span><span class="params">()</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> sum = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//如果任务足够小就计算任务</span></span><br><span class="line">        <span class="keyword">boolean</span> canCompute = (end - start) &lt;= threshold;</span><br><span class="line">        <span class="keyword">if</span>(canCompute)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> i=start; i&lt;=end; i++)</span><br><span class="line">            &#123;</span><br><span class="line">                sum += i;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">        &#123;</span><br><span class="line">            <span class="comment">// 如果任务大于阈值，就分裂成两个子任务计算</span></span><br><span class="line">            <span class="keyword">int</span> middle = (start + end)/<span class="number">2</span>;</span><br><span class="line">            CountTask leftTask = <span class="keyword">new</span> CountTask(start, middle);</span><br><span class="line">            CountTask rightTask = <span class="keyword">new</span> CountTask(middle+<span class="number">1</span>, end);</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 执行子任务</span></span><br><span class="line">            leftTask.fork();</span><br><span class="line">            rightTask.fork();</span><br><span class="line"></span><br><span class="line">            <span class="comment">//等待任务执行结束合并其结果</span></span><br><span class="line">            <span class="keyword">int</span> leftResult = leftTask.join();</span><br><span class="line">            <span class="keyword">int</span> rightResult = rightTask.join();</span><br><span class="line"></span><br><span class="line">            <span class="comment">//合并子任务</span></span><br><span class="line">            sum = leftResult + rightResult;</span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> sum;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        ForkJoinPool forkjoinPool = <span class="keyword">new</span> ForkJoinPool();</span><br><span class="line"></span><br><span class="line">        <span class="comment">//生成一个计算任务，计算1+2+3+4</span></span><br><span class="line">        CountTask task = <span class="keyword">new</span> CountTask(<span class="number">1</span>, <span class="number">100</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//执行一个任务</span></span><br><span class="line">        Future&lt;Integer&gt; result = forkjoinPool.submit(task);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">try</span></span><br><span class="line">        &#123;</span><br><span class="line">            System.out.println(result.get());</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">catch</span>(Exception e)</span><br><span class="line">        &#123;</span><br><span class="line">            System.out.println(e);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>像这种求和以及排序的需求都可以通过FORKJOIN思想来实现，但在实际使用时还是要进行必要的性能测试来确认性能提升的幅度。</p>
<p>在上面这段代码中，定义了一个累加的任务，在compute方法中，判断当前值是否小于一个阈值，如果是则计算，如果不是则继续拆分，并合并子任务的中间结果。</p>
<p>任务定义后执行任务，Fork/Join提供一个和Executor框架的扩展线程来执行任务。</p>
<p>reference:</p>
<ul>
<li><a href="http://www.shareto.me/?p=513" target="_blank" rel="noopener">http://www.shareto.me/?p=513</a></li>
</ul>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://codz-me.vercel.app/2015/07/06/gson-HibernateProxy-serialize-error/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/head.png">
      <meta itemprop="name" content="laudukang">
      <meta itemprop="description" content="Bug Not Found">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Code Is Poetry">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2015/07/06/gson-HibernateProxy-serialize-error/" class="post-title-link" itemprop="url">Gson error: Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy</a>
        </h1>

        <div class="post-meta">
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2015-07-18 17:39:12 17:39:12" itemprop="dateModified" datetime="2015-07-18T17:39:12+08:00">2015-07-18 17:39:12</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Java/" itemprop="url" rel="index">
                    <span itemprop="name">Java</span>
                  </a>
                </span>
            </span>

          
            <span id="/2015/07/06/gson-HibernateProxy-serialize-error/" class="post-meta-item leancloud_visitors" data-flag-title="Gson error: Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy" title="阅读次数">
                <span hidden class="leancloud-visitors-count"></span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>HibernateProxy异常处理</p>
<p>在使用Hibernate时，那么很可能遇到这样的错误：</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java.lang.UnsupportedOperationException: Attempted <span class="keyword">to</span> serialize java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot <span class="keyword">to</span> register a<span class="built_in"> type </span>adapter?</span><br></pre></td></tr></table></figure>
<p>因为gson在转换时是使用的反射机制，当获取的实体对象还在hibernate代理的时候，例如刚通过Id获取到，这时候获取到的便是代理对象HibernateProxy。</p>
<p>这和直接调用实体对象的get方法不同，获取对象的属性就不能起作用。</p>
<p>解决的方法便是将代理对象实例化，见下面的代码</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">    * This TypeAdapter unproxies Hibernate proxied objects, and serializes them</span></span><br><span class="line"><span class="comment">    * through the registered (or default) TypeAdapter of the base class.</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line"></span><br><span class="line">   <span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HibernateProxyTypeAdapter</span> <span class="keyword">extends</span> <span class="title">TypeAdapter</span>&lt;<span class="title">HibernateProxy</span>&gt; </span>&#123;</span><br><span class="line"></span><br><span class="line">   <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> TypeAdapterFactory FACTORY = <span class="keyword">new</span> TypeAdapterFactory() &#123;</span><br><span class="line">       <span class="meta">@Override</span></span><br><span class="line">       <span class="meta">@SuppressWarnings</span>(<span class="string">"unchecked"</span>)</span><br><span class="line">       <span class="keyword">public</span> &lt;T&gt; <span class="function">TypeAdapter&lt;T&gt; <span class="title">create</span><span class="params">(Gson gson, TypeToken&lt;T&gt; type)</span> </span>&#123;</span><br><span class="line">           return (HibernateProxy.class.isAssignableFrom(type.getRawType()) ? (TypeAdapter&lt;T&gt;) new HibernateProxyTypeAdapter(gson) : null);</span><br><span class="line">       &#125;</span><br><span class="line">   &#125;;</span><br><span class="line">   <span class="keyword">private</span> <span class="keyword">final</span> Gson context;</span><br><span class="line"></span><br><span class="line">   <span class="function"><span class="keyword">private</span> <span class="title">HibernateProxyTypeAdapter</span><span class="params">(Gson context)</span> </span>&#123;</span><br><span class="line">       <span class="keyword">this</span>.context = context;</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">   <span class="meta">@Override</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> HibernateProxy <span class="title">read</span><span class="params">(JsonReader in)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">       <span class="keyword">throw</span> <span class="keyword">new</span> UnsupportedOperationException(<span class="string">"Not supported"</span>);</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">   <span class="meta">@SuppressWarnings</span>(&#123;<span class="string">"rawtypes"</span>, <span class="string">"unchecked"</span>&#125;)</span><br><span class="line">   <span class="meta">@Override</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">write</span><span class="params">(JsonWriter out, HibernateProxy value)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">       <span class="keyword">if</span> (value == <span class="keyword">null</span>) &#123;</span><br><span class="line">           out.nullValue();</span><br><span class="line">           <span class="keyword">return</span>;</span><br><span class="line">       &#125;</span><br><span class="line">       <span class="comment">// Retrieve the original (not proxy) class</span></span><br><span class="line">       Class&lt;?&gt; baseType = Hibernate.getClass(value);</span><br><span class="line">       <span class="comment">// Get the TypeAdapter of the original class, to delegate the serialization</span></span><br><span class="line">       TypeAdapter delegate = context.getAdapter(TypeToken.get(baseType));</span><br><span class="line">       <span class="comment">// Get a filled instance of the original class</span></span><br><span class="line">       Object unproxiedValue = ((HibernateProxy) value).getHibernateLazyInitializer()</span><br><span class="line">               .getImplementation();</span><br><span class="line">       <span class="comment">// Serialize the value</span></span><br><span class="line">       delegate.write(out, unproxiedValue);</span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>使用的时候将该TypeAdapter的Factory注册到GsonBuilder,上面的代码变为</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Gson gson = <span class="keyword">new</span> GsonBuilder().setExcludeStrategy(ts)</span><br><span class="line">.registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY)</span><br><span class="line">.create();</span><br><span class="line"></span><br><span class="line">gson.toJson(teacher);</span><br></pre></td></tr></table></figure>

<p>reference:</p>
<ul>
<li><a href="www.17jquery.com/html/54343.html">Gson切面日志实践</a></li>
<li><a href="http://my.oschina.net/orgsky/blog/368768" target="_blank" rel="noopener">GSON序列化时排除字段的几种方式</a></li>
</ul>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://codz-me.vercel.app/2015/06/23/update-ubuntu-user-path-from-zh-to-en/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/head.png">
      <meta itemprop="name" content="laudukang">
      <meta itemprop="description" content="Bug Not Found">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Code Is Poetry">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2015/06/23/update-ubuntu-user-path-from-zh-to-en/" class="post-title-link" itemprop="url">中文 Ubuntu 用户目录里路径改成英文</a>
        </h1>

        <div class="post-meta">
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2015-06-23 21:29:59 21:29:59" itemprop="dateModified" datetime="2015-06-23T21:29:59+08:00">2015-06-23 21:29:59</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Linux/" itemprop="url" rel="index">
                    <span itemprop="name">Linux</span>
                  </a>
                </span>
            </span>

          
            <span id="/2015/06/23/update-ubuntu-user-path-from-zh-to-en/" class="post-meta-item leancloud_visitors" data-flag-title="中文 Ubuntu 用户目录里路径改成英文" title="阅读次数">
                <span hidden class="leancloud-visitors-count"></span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>把中文文件夹改成相应的英文文件夹， 然后编辑配置文件：</p>
<figure class="highlight arcade"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gedit ~<span class="regexp">/.config/u</span>ser-dirs.dirs</span><br></pre></td></tr></table></figure>
<p>把文件夹指向改掉：</p>
<figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">XDG_DESKTOP_DIR</span>=<span class="string">"$HOME/Desktop"</span></span><br><span class="line"><span class="attr">XDG_DOWNLOAD_DIR</span>=<span class="string">"$HOME/Downloads"</span></span><br><span class="line"><span class="attr">XDG_TEMPLATES_DIR</span>=<span class="string">"$HOME/Templates"</span></span><br><span class="line"><span class="attr">XDG_PUBLICSHARE_DIR</span>=<span class="string">"$HOME/Public"</span></span><br><span class="line"><span class="attr">XDG_DOCUMENTS_DIR</span>=<span class="string">"$HOME/Documents"</span></span><br><span class="line"><span class="attr">XDG_MUSIC_DIR</span>=<span class="string">"$HOME/Music"</span></span><br><span class="line"><span class="attr">XDG_PICTURES_DIR</span>=<span class="string">"$HOME/Pictures"</span></span><br><span class="line"><span class="attr">XDG_VIDEOS_DIR</span>=<span class="string">"$HOME/Videos"</span></span><br></pre></td></tr></table></figure>

<p>reference:</p>
<ul>
<li><a href="http://blog.csdn.net/eldn__/article/details/17528541" target="_blank" rel="noopener">http://blog.csdn.net/eldn__/article/details/17528541</a></li>
</ul>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://codz-me.vercel.app/2015/06/10/web-front-end-security/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/head.png">
      <meta itemprop="name" content="laudukang">
      <meta itemprop="description" content="Bug Not Found">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Code Is Poetry">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2015/06/10/web-front-end-security/" class="post-title-link" itemprop="url">[转]Web前端攻防（2014版）</a>
        </h1>

        <div class="post-meta">
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2015-08-17 10:37:12 10:37:12" itemprop="dateModified" datetime="2015-08-17T10:37:12+08:00">2015-08-17 10:37:12</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Linux/" itemprop="url" rel="index">
                    <span itemprop="name">Linux</span>
                  </a>
                </span>
            </span>

          
            <span id="/2015/06/10/web-front-end-security/" class="post-meta-item leancloud_visitors" data-flag-title="[转]Web前端攻防（2014版）" title="阅读次数">
                <span hidden class="leancloud-visitors-count"></span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <h2 id="禁止一切外链资源"><a href="#禁止一切外链资源" class="headerlink" title="禁止一切外链资源"></a>禁止一切外链资源</h2><p>外链会产生站外请求，因此可以被利用实施 CSRF 攻击。</p>
<p>目前国内有大量路由器存在 CSRF 漏洞，其中相当部分用户使用默认的管理账号。通过外链图片，即可发起对路由器 DNS 配置的修改，这将成为国内互联网最大的安全隐患。</p>
<h3 id="案例演示"><a href="#案例演示" class="headerlink" title="案例演示"></a>案例演示</h3><p>百度旅游在富文本过滤时，未考虑标签的 style 属性，导致允许用户自定义的 CSS。因此可以插入站外资源：<br><img src="http://fex.baidu.com/img/web-sec-2014/route-csrf/1.jpg" alt="Web前端攻防（2014版） 第1张" title="Web前端攻防（2014版） 第1张"><br>所有浏览该页面的用户，都能发起任意 URL 的请求：<br><img src="http://fex.baidu.com/img/web-sec-2014/route-csrf/2.jpg" alt="Web前端攻防（2014版） 第2张" title="Web前端攻防（2014版） 第2张"><br>由于站外服务器完全不受控制，攻击者可以控制返回内容：</p>
<ul>
<li>如果检测到是管理员，或者外链检查服务器，可以返回正常图片；</li>
<li>如果是普通用户，可以返回 302 重定向到其他 URL，发起 CSRF 攻击。例如修改路由器 DNS：</li>
</ul>
<figure class="highlight sas"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://admin:admin@192.168.1.1/userRpm/PPPoECfgAdvRpm.htm?wan=0<span class="variable">&amp;lcpMru</span>=1480<span class="variable">&amp;ServiceName</span>=<span class="variable">&amp;AcName</span>=<span class="variable">&amp;EchoReq</span>=0<span class="variable">&amp;manual</span>=2<span class="variable">&amp;dnsserver</span>=黑客服务器<span class="variable">&amp;dnsserver2</span>=4.4.4.4<span class="variable">&amp;downBandwidth</span>=0<span class="variable">&amp;upBandwidth</span>=0<span class="variable">&amp;Save</span>=<span class="name">%B1</span><span class="name">%A3</span>+<span class="name">%B4</span><span class="name">%E6</span><span class="variable">&amp;Advanced</span>=Advanced</span><br></pre></td></tr></table></figure>

<p><img src="http://fex.baidu.com/img/web-sec-2014/route-csrf/3.jpg" alt="Web前端攻防（2014版） 第3张" title="Web前端攻防（2014版） 第3张"><br>演示中，随机测试了几个帖子，在两天时间里收到图片请求 500 多次，已有近 10 个不同的 IP 开始向我们发起 DNS 查询。<br><img src="http://fex.baidu.com/img/web-sec-2014/route-csrf/4.jpg" alt="Web前端攻防（2014版） 第4张" title="Web前端攻防（2014版） 第4张"><br>通过中间人代理，用户的所有隐私都能被捕捉到。还有更严重的后果，查考<a href="http://fex.baidu.com/blog/2014/04/traffic-hijack-2/" target="_blank" rel="noopener">流量劫持危害探讨</a></p>
<p>要是在热帖里『火前留名』，那么数量远不止这些。</p>
<p>如果使用发帖脚本批量回复，将有数以万计的用户网络被劫持。</p>
<h3 id="防范措施"><a href="#防范措施" class="headerlink" title="防范措施"></a>防范措施</h3><p>杜绝用户的一切外链资源。需要站外图片，可以抓回后保存在站内服务器里。</p>
<p>对于富文本内容，使用白名单策略，只允许特定的 CSS 属性。</p>
<p>尽可能开启 Content Security Policy 配置，让浏览器底层来实现站外资源的拦截。</p>
<h2 id="富文本前端扫描"><a href="#富文本前端扫描" class="headerlink" title="富文本前端扫描"></a>富文本前端扫描</h2><p>富文本是 XSS 的重灾区。</p>
<p>富文本的实质是一段 HTML 字符。由于历史原因，HTML 兼容众多不规范的用法，导致过滤起来较复杂。几乎所有使用富文本的产品，都曾出现过 XSS 注入。</p>
<h3 id="案例演示-1"><a href="#案例演示-1" class="headerlink" title="案例演示"></a>案例演示</h3><p>旅游发帖支持富文本，我们继续刚才的演示。<br><img src="http://fex.baidu.com/img/web-sec-2014/richtext/1.jpg" alt="Web前端攻防（2014版） 第5张" title="Web前端攻防（2014版） 第5张"><br>由于之前已修复过几次，目前只能注入 embed 标签和 src 属性。</p>
<p>但即使这样，仍然可以嵌入一个框架页面：<br><img src="http://fex.baidu.com/img/web-sec-2014/richtext/2.jpg" alt="Web前端攻防（2014版） 第6张" title="Web前端攻防（2014版） 第6张"><br>因为是非同源执行的 XSS，所以无法获取主页面的信息。但是可以修改 top.location，将页面跳转到第三方站点。</p>
<p>将原页面嵌入到全屏的 iframe 里，伪造出相同的界面。然后通过浮层登录框，进行钓鱼。<br><img src="http://fex.baidu.com/img/web-sec-2014/richtext/3.jpg" alt="Web前端攻防（2014版） 第7张" title="Web前端攻防（2014版） 第7张"><br>总之，富文本中出现可执行的元素，页面安全性就大打折扣了。</p>
<h3 id="防范措施-1"><a href="#防范措施-1" class="headerlink" title="防范措施"></a>防范措施</h3><p>这里不考虑后端的过滤方法，讲解使用前端预防方案：</p>
<p>无论攻击者使用各种取巧的手段，绕过后端过滤，但这些 HTML 字符最终都要在前端构造成元素，并渲染出来。</p>
<p>因此可以在 DOM 构造之后、渲染之前，对离屏的元素进行风险扫描。将可执行的元素（script，iframe，frame，object，embed，applet）从缓存中移除。</p>
<p>或者给存在风险的元素，加上沙箱隔离属性。</p>
<ul>
<li>例如 iframe 加上 sandbox 属性，即可只显示框架内容而不运行脚本</li>
<li>例如 Flash 加上 allowScriptAccess 及 allowNetworking，也能起到一定的隔离作用。</li>
</ul>
<p>DOM 仅仅被构造是不会执行的，只有添加到主节点被渲染时才会执行。所以这个过程中间，可以实施安全扫描。</p>
<p>实现细节可以参考：<a href="http://www.etherdream.com/FunnyScript/richtext_safe_render.html" target="_blank" rel="noopener">http://www.etherdream.com/FunnyScript/richtextsaferender.html</a></p>
<p>如果富文本是直接输入到静态页面里的，可以考虑使用 MutationEvent 进行防御。详细参考：<a href="http://fex.baidu.com/blog/2014/06/xss-frontend-firewall-2/" target="_blank" rel="noopener">http://fex.baidu.com/blog/2014/06/xss-frontend-firewall-2/</a></p>
<p>但推荐使用动态方式进行渲染，可扩展性更强，并且性能消耗最小。</p>
<h2 id="跳转-opener-钓鱼"><a href="#跳转-opener-钓鱼" class="headerlink" title="跳转 opener 钓鱼"></a>跳转 opener 钓鱼</h2><p>浏览器提供了一个 opener 属性，供弹出的窗口访问来源页。但该规范设计的并不合理，导致通过超链接打开的页面，也能使用 opener。</p>
<p>因此，用户点了网站里的超链接，导致原页面被打开的第三方页面控制。</p>
<p>虽然两者受到同源策略的限制，第三方无法访问原页面内容，但可以跳转原页面。</p>
<p>由于用户的焦点在新打开的页面上，所以原页面被悄悄跳转，用户难以觉察到。当用户切回原页面时，其实已经在另一个钓鱼网站上了。</p>
<h3 id="案例演示-2"><a href="#案例演示-2" class="headerlink" title="案例演示"></a>案例演示</h3><p>百度贴吧目前使用的超链接，就是在新窗口中弹出，因此同样存在该缺陷。</p>
<p>攻击者发一个吸引用户的帖子。当用户进来时，引诱他们点击超链接。</p>
<p>通常故意放少部分的图片，或者是不会动的动画，先让用户预览一下。要是用户想看完整的，就得点下面的超链接：<br><img src="http://fex.baidu.com/img/web-sec-2014/chg-opener/1.jpg" alt="Web前端攻防（2014版） 第8张" title="Web前端攻防（2014版） 第8张"><br>由于扩展名是 gif 等图片格式，大多用户就毫无顾虑的点了。</p>
<p>事实上，真正的类型是由服务器返回的 MIME 决定的。所以这个站外资源完全有可能是一个网页：<br><img src="http://fex.baidu.com/img/web-sec-2014/chg-opener/2.jpg" alt="Web前端攻防（2014版） 第9张" title="Web前端攻防（2014版） 第9张"><br>当用户停留在新页面里看动画时，隐匿其中的脚本已悄悄跳转原页面了。</p>
<p>用户切回原页面时，其实已在一个钓鱼网站上：<br><img src="http://fex.baidu.com/img/web-sec-2014/chg-opener/3.jpg" alt="Web前端攻防（2014版） 第10张" title="Web前端攻防（2014版） 第10张"><br>在此之上，加些浮层登录框等特效，很有可能钓到用户的一些账号信息。</p>
<h3 id="防范措施-2"><a href="#防范措施-2" class="headerlink" title="防范措施"></a>防范措施</h3><p>该缺陷是因为 opener 这个属性引起的，所以得屏蔽掉新页面的这个属性。</p>
<p>但通过超链接打开的网页，无法被脚本访问到。只有通过 window.open 弹出的窗口，才能获得其对象。</p>
<p>所以，对页面中的用户发布的超链接，监听其点击事件，阻止默认的弹窗行为，而是用 window.open 代替，并将返回窗体的 opener 设置为 null，即可避免第三方页面篡改了。</p>
<p>详细实现参考：<a href="http://www.etherdream.com/FunnyScript/opener_protect.html" target="_blank" rel="noopener">http://www.etherdream.com/FunnyScript/opener_protect.html</a></p>
<p>当然，实现中无需上述 Demo 那样复杂。根据实际产品线，只要监听用户区域的超链接就可以。</p>
<h2 id="用户内容权限"><a href="#用户内容权限" class="headerlink" title="用户内容权限"></a>用户内容权限</h2><p>支持自定义装扮的场合，往往是钓鱼的高发区。</p>
<p>一些别有用心者，利用装扮来模仿系统界面，引诱用户上钩。</p>
<h3 id="案例演示-空间越界"><a href="#案例演示-空间越界" class="headerlink" title="案例演示 - 空间越界"></a>案例演示 - 空间越界</h3><p>百度空间允许用户撰写自定格式的内容。</p>
<p>其本质是一个富文本编辑器，这里不演示 XSS 漏洞，而是利用样式装扮，伪装一个钓鱼界面。</p>
<p>百度空间富文本过滤元素、部分属性及 CSS 样式，但未对 class 属性启用白名单，因此可以将页面上所有的 CSS 类样式，应用到自己的内容上来。<br><img src="http://fex.baidu.com/img/web-sec-2014/decorate-limit/out-of-bound.jpg" alt="Web前端攻防（2014版） 第11张" title="Web前端攻防（2014版） 第11张"></p>
<h3 id="防范措施-3"><a href="#防范措施-3" class="headerlink" title="防范措施"></a>防范措施</h3><p>规定用户内容尺寸限制，可以在提交时由用户自己确定。</p>
<p>不应该为用户的内容分配无限的尺寸空间，以免恶意用户设置超大字体，破坏整个页面的浏览。</p>
<p>最好将用户自定义的内容嵌套在 iframe 里，以免影响到页面其他部位。</p>
<p>如果必须在同页面，应将用户内容所在的容器，设置超过部分不可见。以免因不可预测的 BUG，导致用户能将内容越界到产品界面上。</p>
<h3 id="案例演示-功能越界"><a href="#案例演示-功能越界" class="headerlink" title="案例演示 - 功能越界"></a>案例演示 - 功能越界</h3><p>自定义装扮通常支持站外超链接。</p>
<p>相比贴吧这类简单纯文字，富文本可以将超链接设置在其他元素上，例如图片。</p>
<p>因此这类链接非常具有迷惑性，用户不经意间就点击到。很容易触发之前提到的修改 opener 钓鱼。<br><img src="http://fex.baidu.com/img/web-sec-2014/decorate-limit/download-phishing-1.jpg" alt="Web前端攻防（2014版） 第12张" title="Web前端攻防（2014版） 第12张"><br>如果在图片内容上进行伪装，更容易让用户触发一些危险操作。<br><img src="http://fex.baidu.com/img/web-sec-2014/decorate-limit/download-phishing-2.jpg" alt="Web前端攻防（2014版） 第13张" title="Web前端攻防（2014版） 第13张"><br>要是和之前的区域越界配合使用，迷惑性则更强：<br><img src="http://fex.baidu.com/img/web-sec-2014/decorate-limit/plugin-phishing-1.jpg" alt="Web前端攻防（2014版） 第14张" title="Web前端攻防（2014版） 第14张"><br><img src="http://fex.baidu.com/img/web-sec-2014/decorate-limit/plugin-phishing-2.jpg" alt="Web前端攻防（2014版） 第15张" title="Web前端攻防（2014版） 第15张"></p>
<h3 id="防范措施-4"><a href="#防范措施-4" class="headerlink" title="防范措施"></a>防范措施</h3><p>和之前一样，对于用户提供的超链接，在点击时进行扫描。如果是站外地址，则通过后台跳转进入，以便后端对 URL 进行安全性扫描。</p>
<p>如果服务器检测到是一个恶意网站，或者目标资源是可执行文件，应给予用户强烈的警告，告知其风险。</p>
<h2 id="点击劫持检测"><a href="#点击劫持检测" class="headerlink" title="点击劫持检测"></a>点击劫持检测</h2><p>点击劫持算是比较老的攻击方式了，基本原理大家也都听说过。就是在用户不知情的前提下，点击隐藏框架页面里的按钮，触发一些重要操作。</p>
<p>但目前在点击劫持上做防御的并不多，包括百度绝大多数产品线目前都未考虑。</p>
<h3 id="案例演示-3"><a href="#案例演示-3" class="headerlink" title="案例演示"></a>案例演示</h3><p>能直接通过点击完成的操作，比较有意义的就是关注某用户。例如百度贴吧加关注的按钮：<br><img src="http://fex.baidu.com/img/web-sec-2014/clickjacking/1.jpg" alt="Web前端攻防（2014版） 第16张" title="Web前端攻防（2014版） 第16张"><br>攻击者事先算出目标按钮的尺寸和坐标，将页面嵌套在自己框架里，并设置框架的偏移，最终只显示按钮：<br><img src="http://fex.baidu.com/img/web-sec-2014/clickjacking/2.jpg" alt="Web前端攻防（2014版） 第17张" title="Web前端攻防（2014版） 第17张"><br>接着通过 CSS 样式，将目标按钮放大，占据整个页面空间，并设置全透明。<br><img src="http://fex.baidu.com/img/web-sec-2014//clickjacking/3.jpg" alt="Web前端攻防（2014版） 第18张" title="Web前端攻防（2014版） 第18张"><br>这时虽看不到按钮，但点击页面任意位置，都能触发框架页中加关注按钮的点击：<br><img src="http://fex.baidu.com/img/web-sec-2014/clickjacking/4.jpg" alt="Web前端攻防（2014版） 第19张" title="Web前端攻防（2014版） 第19张"></p>
<h3 id="防范措施-5"><a href="#防范措施-5" class="headerlink" title="防范措施"></a>防范措施</h3><p>事实上，点击劫持是很好防御的。</p>
<p>因为自身页面被嵌套在第三方页面里，只需判断 self == top 即可获知是否被嵌套。</p>
<p>对一些重要的操作，例如加关注、删帖等，应先验证是否被嵌套。如果处于第三方页面的框架里，应弹出确认框提醒用户。</p>
<p>确认框的坐标位置最好有一定的随机偏移，从而使攻击者构造的点击区域失效。</p>
<div id="dxseo-related-posts" style="clear:both;">

<h3 id="相关文章"><a href="#相关文章" class="headerlink" title="相关文章"></a>相关文章</h3><ul>
<li><a href="http://www.he11oworld.com/ebook/1402.html" target="_blank" rel="noopener" title="小小黑客之路 黑客工具、攻防及防火墙编程入门">小小黑客之路 黑客工具、攻防及防火墙编程入门</a></li>
<li><a href="http://www.he11oworld.com/anquan/shentou/1235" target="_blank" rel="noopener" title="风云网络VIP网站攻防安全课程">风云网络VIP网站攻防安全课程</a></li>
<li><a href="http://www.he11oworld.com/front-end/2653.html" target="_blank" rel="noopener" title="Web前端开发视频教程 价值2200元前端专业课">Web前端开发视频教程 价值2200元前端专业课</a></li>
<li><a href="http://www.he11oworld.com/anquan/shentou/1256" target="_blank" rel="noopener" title="黑客攻防之网站攻防修炼">黑客攻防之网站攻防修炼</a></li>
<li><a href="http://www.he11oworld.com/ebook/1067.html" target="_blank" rel="noopener" title="无线网络安全攻防实战完整版">无线网络安全攻防实战完整版</a></li>
</ul>
<p>reference:</p>
<ul>
<li><a href="http://www.he11oworld.com/security/1114.html" target="_blank" rel="noopener">http://www.he11oworld.com/security/1114.html</a></li>
</ul>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://codz-me.vercel.app/2015/06/05/chrome-skills-repost/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/head.png">
      <meta itemprop="name" content="laudukang">
      <meta itemprop="description" content="Bug Not Found">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Code Is Poetry">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2015/06/05/chrome-skills-repost/" class="post-title-link" itemprop="url">[转]史上最全的Chrome使用技巧集锦</a>
        </h1>

        <div class="post-meta">
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2015-08-14 16:58:31 16:58:31" itemprop="dateModified" datetime="2015-08-14T16:58:31+08:00">2015-08-14 16:58:31</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Chrome/" itemprop="url" rel="index">
                    <span itemprop="name">Chrome</span>
                  </a>
                </span>
            </span>

          
            <span id="/2015/06/05/chrome-skills-repost/" class="post-meta-item leancloud_visitors" data-flag-title="[转]史上最全的Chrome使用技巧集锦" title="阅读次数">
                <span hidden class="leancloud-visitors-count"></span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <h2 id="Chrome的隐身模式"><a href="#Chrome的隐身模式" class="headerlink" title="Chrome的隐身模式"></a>Chrome的隐身模式</h2><p>先来说说隐身模式的启用方法吧</p>
<p>1.键盘快捷：Ctrl + Shift + N。</p>
<p>2.在Windows7下的任务栏处，右击“Chrome”图标，会出一个下拉菜单，点击“新建隐身窗口”。</p>
<p><img src="http://static.codeceo.com/images/2015/02/cbd5e972f57b108337c8e3625a1aa59e.png" alt=""></p>
<p>3.你还可以在一个正在浏览的页面中，通过“右键点击链接”出现下拉菜单，选择“在隐身窗口中打开链接”，直接进入隐身窗口（如下图）。</p>
<p><img src="http://static.codeceo.com/images/2015/02/dd8e476f2a1edde3693f7d94f2ba32ee.png" alt=""></p>
<p>简单一点的说，Chrome的隐身模式的好处就是保持你的隐私。具体表现在在此窗口中查看的网页不会显示在浏览器历史记录或搜索历史记录中，关闭隐身窗口后也不会在计算机上留下 Cookie 之类的其他痕迹，但会保留所有下载的文件或创建的书签，一般什么情境下你会使用Chrome的隐身模式呢</p>
<p>1、在注册网上银行等业务方面的网站时</p>
<p>2、你用朋友的电脑上网，而又不想在“历史记录”中被他发现你上了哪些网站</p>
<p>Chrome最强大的地方莫过于有各种各样的插件了，那如何在隐身模式下启用或禁用插件呢？点击右上角“扳手“–》”更多工具“–》”扩展程序”，在这个页面中，你可以选择哪些插件可以用于Chrome的隐身模式</p>
<p><img src="http://static.codeceo.com/images/2015/02/3248ee61a830fa9aa2f3fac1183f6c79.png" alt=""></p>
<p>事实上隐身模式并非是万能的，Chrome给出的建议是在以下一些情况下谨防失效：</p>
<ul>
<li>收集或共享有关您的信息的网站</li>
<li>跟踪您访问的网页的互联网服务提供商或雇主</li>
<li>以提供免费表情符号的名义跟踪您击键情况的恶意软件</li>
<li>通过秘密代理进行监视的行为</li>
<li>站在身后的人</li>
</ul>
<h2 id="Chrome下各种组合键"><a href="#Chrome下各种组合键" class="headerlink" title="Chrome下各种组合键"></a>Chrome下各种组合键</h2><table>

<tbody>

<tr>

<th>热键组合</th>

<th>实现的功能</th>

</tr>

<tr>

<td>F1</td>

<td>Google浏览器帮助中心</td>

</tr>

<tr>

<td>F12</td>

<td>打开<span class="wp_keywordlink">[Chrome控制台](http://www.codeceo.com/article/chrome-console.html "Chrome控制台")</span></td>

</tr>

<tr>

<td>Ctrl+J</td>

<td>进入“下载内容”页面</td>

</tr>

<tr>

<td>Ctrl+H</td>

<td>查看“历史记录”页面</td>

</tr>

<tr>

<td>Ctrl+D</td>

<td>将此页加入书签</td>

</tr>

<tr>

<td>Ctrl+F</td>

<td>打开/关闭 搜索框（搜索页面内的文字）</td>

</tr>

<tr>

<td>Ctrl+P</td>

<td>打开打印窗口</td>

</tr>

<tr>

<td>Ctrl+T</td>

<td>新建标签页</td>

</tr>

<tr>

<td>Ctrl+W</td>

<td>关闭标签页</td>

</tr>

<tr>

<td>Ctrl++</td>

<td>放大页面</td>

</tr>

<tr>

<td>Ctrl+-</td>

<td>缩小页面</td>

</tr>

<tr>

<td>Ctrl+0</td>

<td>默认页面字体大小</td>

</tr>

<tr>

<td>Ctrl+Shift+T</td>

<td>重新打开最近关闭的一个标签</td>

</tr>

<tr>

<td>Ctrl+N</td>

<td>新建一个窗口</td>

</tr>

<tr>

<td>Ctrl+Shift+N</td>

<td>新建一个隐身模式窗口</td>

</tr>

<tr>

<td>Ctrl+Tab</td>

<td>从左到右，标签循环浏览</td>

</tr>

<tr>

<td>Ctrl+Shift+Tab</td>

<td>从右到左，标签循环浏览</td>

</tr>

<tr>

<td>Ctrl+1-8</td>

<td>分别指向第1、2、3…8标签</td>

</tr>

<tr>

<td>Ctrl+9</td>

<td>跳转到最后一个标签</td>

</tr>

<tr>

<td>Ctrl+Shift+Del</td>

<td>打开“清除浏览数据”窗口</td>

</tr>

<tr>

<td>Ctrl+Shift+B</td>

<td>显示/隐藏书签栏</td>

</tr>

<tr>

<td>Shift+Esc</td>

<td>开打Chrome任务管理器</td>

</tr>

<tr>

<td>Alt+Home</td>

<td>在当前标签打开首页</td>

</tr>

<tr>

<td>Alt+D/Ctrl+L</td>

<td>迅速突出地址栏</td>

</tr>

<tr>

<td>Ctrl+Enter</td>

<td>在地址栏自动添加www或.com</td>

</tr>

<tr>

<td>Ctrl+Shift+V</td>

<td>粘帖剪切板中的纯文本格式</td>

</tr>

<tr>

<td>Shift+Alt+T</td>

<td>将焦点聚集到工具栏中的第一个工具</td>

</tr>

<tr>

<td>Tab (after Shift+Alt+T)</td>

<td>工具栏中将焦点移到各个选项上</td>

</tr>

<tr>

<td>Space or Enter (after Shift+Alt+T)</td>

<td>可激活工具栏按钮</td>

</tr>

<tr>

<td>Shift+F10 (after Shift+Alt+T)</td>

<td>可打开相关右键菜单</td>

</tr>

<tr>

<td>Esc (after Shift+Alt+T)</td>

<td>可将焦点从工具栏移回到网页上</td>

</tr>

</tbody>

</table>

<h2 id="Chrome的about指令"><a href="#Chrome的about指令" class="headerlink" title="Chrome的about指令"></a>Chrome的about指令</h2><p>估计很多人不知道Chrome地址栏功能，作为一个Chrome用户，必须懂的。以下我要介绍的这些指令在Chrome地址栏输入即可</p>
<p>about:version – 显示当前版本 也可以是chrome-resource://about/</p>
<p>about:plugins – 显示已安装插件</p>
<p>about:histograms – 显示历史记录</p>
<p>chrome://history2 – 浏览历史 History2</p>
<p>about:dns – 显示DNS状态</p>
<p>about:cache, 重定向到 view-cache: 显示缓存页面</p>
<p>view-cache:stats – 缓存状态</p>
<p>about:stats – 显示状态</p>
<p>chrome-resource://new-tab/ – 新标签页</p>
<p>about:memory – 可以查看内存和进程占用。也可以Shift+ESC，点击Statistics for nerds（傻瓜统计信息）</p>
<p>about:flags – Chrome高级设置</p>
<p>也许大家看到上面 这一大片的指令，估计都没有动手去试试的欲望了。</p>
<p>事实上你根本就无需记这些指令，你只需要记住一个万能的就行，那就是<strong>chrome://about/</strong></p>
<p><strong>你在Chrome地址栏输入这个，就会出现如下截图，哈哈，万能吧！（还有好多，我只截了一部分哦）</strong></p>
<p><strong><img src="http://static.codeceo.com/images/2015/02/df4394bf452b8a5d3ff58d77bc6d399f.png" alt=""></strong></p>
<p>下面我就针对一些重要的指令一一介绍一下！（别嫌麻烦哦，真心挺有用的）</p>
<h2 id="chrome-accessibility-查看浏览器当前访问的标签"><a href="#chrome-accessibility-查看浏览器当前访问的标签" class="headerlink" title="chrome://accessibility     查看浏览器当前访问的标签"></a>chrome://accessibility     查看浏览器当前访问的标签</h2><p>用于查看浏览器当前访问的标签，打开全局访问模式可以查看：各个标签页面的文档系统树，大家看到的效果图如下所示：</p>
<p><img src="http://static.codeceo.com/images/2015/02/bcd6135c7099d1166a400f09b3133008.png" alt=""></p>
<h2 id="chrome-appcache-internals-对HTML5应用的离线存储进行管理"><a href="#chrome-appcache-internals-对HTML5应用的离线存储进行管理" class="headerlink" title="chrome://appcache-internals/    对HTML5应用的离线存储进行管理"></a>chrome://appcache-internals/    对HTML5应用的离线存储进行管理</h2><p>这个我就不细说了，只有你浏览HTML5网站时才会有显示缓存记录，这时用这个命令就可以对HTML5应用的离线存储进行管理</p>
<h2 id="chrome-apps-Chrome网上应用商店"><a href="#chrome-apps-Chrome网上应用商店" class="headerlink" title="chrome://apps/      Chrome网上应用商店"></a>chrome://apps/      Chrome网上应用商店</h2><p>使用这个命令就可以快速打开Chrome网上应用商店</p>
<h2 id="chrome-bookmarks-Chrome书签管理"><a href="#chrome-bookmarks-Chrome书签管理" class="headerlink" title="chrome://bookmarks     Chrome书签管理"></a>chrome://bookmarks     Chrome书签管理</h2><p>相信大家平常少不了用书签来记录一些自己认为特别好的网站以便后时之需。哈哈，这时这条命令就派上用场了。</p>
<h2 id="chrome-cache-Chrome缓存"><a href="#chrome-cache-Chrome缓存" class="headerlink" title="chrome://cache/      Chrome缓存"></a>chrome://cache/      Chrome缓存</h2><p>哎，对于这个指令，我只能说看看而已吧，别太认真了。因为它只能用于查看，却不能进行其它操作。</p>
<p>不过，虽然是查看，却可以带来异样的感觉。比如说点击某个缓存的图片文件它会用16进制的方法显示缓存文件</p>
<p><img src="http://static.codeceo.com/images/2015/02/7d69a5fb6fcefc236ecb1583883131d7.png" alt=""></p>
<h2 id="关于Chrome-chrome-chrome-和chrome-help"><a href="#关于Chrome-chrome-chrome-和chrome-help" class="headerlink" title="关于Chrome     chrome://chrome/和chrome://help/"></a>关于Chrome     chrome://chrome/和chrome://help/</h2><p>想自动升级Chrome的用它吧，不过不知道为什么有两条指令。（不过也许这就是条条大道通罗马吧  哈哈  扯远了）</p>
<h2 id="关于Chrome的相关功能-chrome-about-和chrome-chrome-urls"><a href="#关于Chrome的相关功能-chrome-about-和chrome-chrome-urls" class="headerlink" title="关于Chrome的相关功能    chrome://about/和chrome://chrome-urls/"></a>关于Chrome的相关功能    chrome://about/和chrome://chrome-urls/</h2><p>显示所有 chrome 的相关功能的连接</p>
<h2 id="chrome-components-查看相关组件"><a href="#chrome-components-查看相关组件" class="headerlink" title="chrome://components/     查看相关组件"></a>chrome://components/     查看相关组件</h2><p>如果你相看看相关组件是否需要升级，可以使用它哦。</p>
<p><img src="http://static.codeceo.com/images/2015/02/41e30d2d8c58df601d516acbde435c25.png" alt=""></p>
<h2 id="chrome-conflicts-查看所有已经载入或者将要载入主要程序中的-dll-模块"><a href="#chrome-conflicts-查看所有已经载入或者将要载入主要程序中的-dll-模块" class="headerlink" title="chrome://conflicts/     查看所有已经载入或者将要载入主要程序中的 dll 模块"></a>chrome://conflicts/     查看所有已经载入或者将要载入主要程序中的 dll 模块</h2><p>这个功能不太懂是….也许是为了调试用的吧</p>
<p><img src="http://static.codeceo.com/images/2015/02/99bc57581fabcaba88562b5f81a30553.png" alt=""></p>
<h2 id="chrome-crashes-停用启用崩溃报告"><a href="#chrome-crashes-停用启用崩溃报告" class="headerlink" title="chrome://crashes/    停用启用崩溃报告"></a>chrome://crashes/    停用启用崩溃报告</h2><p>如果启用的话将使用情况统计信息和崩溃报告自动发送给 Google</p>
<p><img src="http://static.codeceo.com/images/2015/02/38dadcb2e6c8188dc4252eaa39c13f89.png" alt=""></p>
<h2 id="chrome-credits-查看第三方软件许可证"><a href="#chrome-credits-查看第三方软件许可证" class="headerlink" title="chrome://credits/     查看第三方软件许可证"></a>chrome://credits/     查看第三方软件许可证</h2><p>除此之外还可以查看某个软件的主页（源码），点击下图所示的show license试试</p>
<p><img src="http://static.codeceo.com/images/2015/02/c323508d8bfcd55fcdc450517d488c64.png" alt=""></p>
<h2 id="chrome-devices"><a href="#chrome-devices" class="headerlink" title="chrome://devices/"></a>chrome://devices/</h2><p>查看设备，比如链接的打印机</p>
<h2 id="chrome-dns-查看DNS记录"><a href="#chrome-dns-查看DNS记录" class="headerlink" title="chrome://dns/      查看DNS记录"></a>chrome://dns/      查看DNS记录</h2><p>DNS记录查看，如果有网络故障记得先来找他，chrome 还会定时更新hosts的DNS</p>
<p><img src="http://static.codeceo.com/images/2015/02/e0131f2fa5bc264b21b94be1e06be069.png" alt=""></p>
<h2 id="chrome-downloads-查看下载文件"><a href="#chrome-downloads-查看下载文件" class="headerlink" title="chrome://downloads/     查看下载文件"></a>chrome://downloads/     查看下载文件</h2><p>查看下载文件的记录。这个命令太有用了。也是我最最经常使用的。</p>
<h2 id="chrome-extensions-查看扩展程序"><a href="#chrome-extensions-查看扩展程序" class="headerlink" title="chrome://extensions/     查看扩展程序"></a>chrome://extensions/     查看扩展程序</h2><p>这个没啥好说的，大家都知道Chrome最强大的地方就在于有各种各校的插件和各式各样的扩展程序。那这些扩展程序主要是干嘛呢，无非就是由某些大神开发用于提高咱们的工作效率的</p>
<h2 id="chrome-plugins-停用启用相关插件"><a href="#chrome-plugins-停用启用相关插件" class="headerlink" title="chrome://plugins/      停用启用相关插件"></a>chrome://plugins/      停用启用相关插件</h2><h2 id="chrome-flags"><a href="#chrome-flags" class="headerlink" title="chrome://flags/"></a>chrome://flags/</h2><p>这个更没啥好说的，没专业技能不要修改默认设置，比如 GPU的某些设置。</p>
<p><img src="http://static.codeceo.com/images/2015/02/95f8a512cbb3005d53af8bc90beacab1.png" alt=""></p>
<h2 id="chrome-flash-flash插件的详细信息"><a href="#chrome-flash-flash插件的详细信息" class="headerlink" title="chrome://flash/      flash插件的详细信息"></a>chrome://flash/      flash插件的详细信息</h2><p><img src="http://static.codeceo.com/images/2015/02/3c43b7119cfa6fd1656abc1790ded5ed.png" alt=""></p>
<h2 id="chrome-gcm-internals-消息推送服务"><a href="#chrome-gcm-internals-消息推送服务" class="headerlink" title="chrome://gcm-internals/     消息推送服务"></a>chrome://gcm-internals/     消息推送服务</h2><p>Google Cloud Messaging for Android 是谷歌新推出的云推送消息服务，简称 <code>GCM。该服务可帮助你将数据从服务端发送至应用</code></p>
<h2 id="chrome-history-查看历史记录"><a href="#chrome-history-查看历史记录" class="headerlink" title="chrome://history/      查看历史记录"></a>chrome://history/      查看历史记录</h2><p>查看访问的历史记录</p>
<h2 id="chrome-indexeddb-internals-查看-html5的本地存储"><a href="#chrome-indexeddb-internals-查看-html5的本地存储" class="headerlink" title="chrome://indexeddb-internals/      查看 html5的本地存储"></a>chrome://indexeddb-internals/      查看 html5的本地存储</h2><p>列出使用你本地存储的 html5站点，然后你可以“强制清除”它，或者“下载”它</p>
<p><img src="http://static.codeceo.com/images/2015/02/99b6b10612d663e62ebf8fb686298e58.png" alt=""></p>
<h2 id="chrome-inspect-查看开发工具"><a href="#chrome-inspect-查看开发工具" class="headerlink" title="chrome://inspect/     查看开发工具"></a>chrome://inspect/     查看开发工具</h2><p>这个对于开发人员来说应该最体贴的功能啦，包括设备、检查页面 、扩展、App、共享、服务等选项卡。上图就知道了</p>
<p><img src="http://static.codeceo.com/images/2015/02/c57090674e4787446aa2cac0211e5ba1.png" alt=""></p>
<h2 id="chrome-invalidations-失效的调试程序"><a href="#chrome-invalidations-失效的调试程序" class="headerlink" title="chrome://invalidations/    失效的调试程序"></a>chrome://invalidations/    失效的调试程序</h2><p>失效的调试信息，可以查看调试日志以及内部详细信息。这个我还真没摸出它的价值来，有知道的可以告诉我一下。</p>
<h2 id="chrome-media-internals-查看媒体内部数据"><a href="#chrome-media-internals-查看媒体内部数据" class="headerlink" title="chrome://media-internals/     查看媒体内部数据"></a>chrome://media-internals/     查看媒体内部数据</h2><p>用来调试在线播放的一些数据，比如测试 音频流</p>
<h2 id="chrome-memory-redirect-查看内存信息"><a href="#chrome-memory-redirect-查看内存信息" class="headerlink" title="chrome://memory-redirect/     查看内存信息"></a>chrome://memory-redirect/     查看内存信息</h2><p>查看 chrome 各个 网页标签、插件 消耗的内存</p>
<p><img src="http://static.codeceo.com/images/2015/02/fe380dd35ebecd2d64005ab4b6ebf570.png" alt=""></p>
<h2 id="chrome-memory-internals"><a href="#chrome-memory-internals" class="headerlink" title="chrome://memory-internals/"></a>chrome://memory-internals/</h2><p>每个页面、插件详细的内存信息；点击 <kbd>Update</kbd> 可以获取json格式的进程，以及可视化的信息：PID、Name(Browser/GPU/TAB/History)、Memory……</p>
<p><img src="http://static.codeceo.com/images/2015/02/74c054e53904c0ff7bbb5750ac0a21e0.png" alt=""></p>
<h2 id="chrome-nacl"><a href="#chrome-nacl" class="headerlink" title="chrome://nacl/"></a>chrome://nacl/</h2><p>本地客户端 Native Client 环境信息，包括浏览器、操作系统、插件等</p>
<p><img src="http://static.codeceo.com/images/2015/02/d9e2ec36250f624dbd4a15086383f539.png" alt=""></p>
<h3 id="chrome-net-internals-Chrome的抓包工具"><a href="#chrome-net-internals-Chrome的抓包工具" class="headerlink" title="chrome://net-internals     Chrome的抓包工具"></a>chrome://net-internals     Chrome的抓包工具</h3><p><img src="http://static.codeceo.com/images/2015/02/c734d4012ec7d78ffd817bd1e326fabd.png" alt=""></p>
<h2 id="chrome-newtab-打开新的标签"><a href="#chrome-newtab-打开新的标签" class="headerlink" title="chrome://newtab     打开新的标签"></a>chrome://newtab     打开新的标签</h2><h2 id="chrome-omnibox-智能地址栏"><a href="#chrome-omnibox-智能地址栏" class="headerlink" title="chrome://omnibox/     智能地址栏"></a>chrome://omnibox/     智能地址栏</h2><p>我只能说这个大强大了，太实用了。你用用就知道它的厉害了</p>
<p><img src="http://static.codeceo.com/images/2015/02/b5530fec1a752062856b6ce6a38880e4.png" alt=""></p>
<h2 id="chrome-predictors-URl输入命中率"><a href="#chrome-predictors-URl输入命中率" class="headerlink" title="chrome://predictors/    URl输入命中率"></a>chrome://predictors/    URl输入命中率</h2><p>结合 <code>omnibox</code> 一起使用看看的智能程序。</p>
<p><img src="http://static.codeceo.com/images/2015/02/06530a5a31e570396583844adf974b3e.png" alt=""></p>
<h2 id="chrome-policy-编辑策略"><a href="#chrome-policy-编辑策略" class="headerlink" title="chrome://policy/   编辑策略"></a>chrome://policy/   编辑策略</h2><h2 id="chrome-print-调用打印机"><a href="#chrome-print-调用打印机" class="headerlink" title="chrome://print/   调用打印机"></a>chrome://print/   调用打印机</h2><h2 id="chrome-profiler-分析器"><a href="#chrome-profiler-分析器" class="headerlink" title="chrome://profiler/   分析器"></a>chrome://profiler/   分析器</h2><p><img src="http://static.codeceo.com/images/2015/02/4d2ff86e3b0319d3a61842c310b41fd8.png" alt=""></p>
<h2 id="chrome-serviceworker-internals-调试服务"><a href="#chrome-serviceworker-internals-调试服务" class="headerlink" title="chrome://serviceworker-internals/    调试服务"></a>chrome://serviceworker-internals/    调试服务</h2><h2 id="chrome-quota-internals-显示磁盘详细可用空间以及各个网站的使用配额"><a href="#chrome-quota-internals-显示磁盘详细可用空间以及各个网站的使用配额" class="headerlink" title="chrome://quota-internals/  显示磁盘详细可用空间以及各个网站的使用配额"></a>chrome://quota-internals/  显示磁盘详细可用空间以及各个网站的使用配额</h2><h2 id="chrome-settings-设置"><a href="#chrome-settings-设置" class="headerlink" title="chrome://settings/    设置"></a>chrome://settings/    设置</h2><h2 id="chrome-signin-internals-内部标签"><a href="#chrome-signin-internals-内部标签" class="headerlink" title="chrome://signin-internals/     内部标签"></a>chrome://signin-internals/     内部标签</h2><p>包括，基础信息、上一次更新、登陆令牌、账户</p>
<p><img src="http://static.codeceo.com/images/2015/02/34658e36d1d25b233950fb1746850019.png" alt=""></p>
<h2 id="chrome-sync-internals-各种同步记录"><a href="#chrome-sync-internals-各种同步记录" class="headerlink" title="chrome://sync-internals/     各种同步记录"></a>chrome://sync-internals/     各种同步记录</h2><h2 id="chrome-system-系统诊断数据"><a href="#chrome-system-系统诊断数据" class="headerlink" title="chrome://system/    系统诊断数据"></a>chrome://system/    系统诊断数据</h2><h2 id="chrome-terms-查看Chrome服务条款"><a href="#chrome-terms-查看Chrome服务条款" class="headerlink" title="chrome://terms/    查看Chrome服务条款"></a>chrome://terms/    查看Chrome服务条款</h2><h2 id="chrome-thumbnails-近期浏览的网站的首页快照（以相册的形式）"><a href="#chrome-thumbnails-近期浏览的网站的首页快照（以相册的形式）" class="headerlink" title="chrome://thumbnails/    近期浏览的网站的首页快照（以相册的形式）"></a>chrome://thumbnails/    近期浏览的网站的首页快照（以相册的形式）</h2><p>我不得不说一下，这个确实好玩。（还是忍不住暴露了一下女生天生爱玩的特质）</p>
<p><img src="http://static.codeceo.com/images/2015/02/c57b1f00edb148d5264eceb68e07f971.png" alt=""></p>
<h2 id="chrome-translate-internals-内部翻译器"><a href="#chrome-translate-internals-内部翻译器" class="headerlink" title="chrome://translate-internals/    内部翻译器"></a>chrome://translate-internals/    内部翻译器</h2><h2 id="chrome-tracing-追踪访问URL，包括浏览和渲染的过程"><a href="#chrome-tracing-追踪访问URL，包括浏览和渲染的过程" class="headerlink" title="chrome://tracing/    追踪访问URL，包括浏览和渲染的过程"></a>chrome://tracing/    追踪访问URL，包括浏览和渲染的过程</h2><p>这个对开发人员来说太实用了。上图就知道啦</p>
<p><img src="http://static.codeceo.com/images/2015/02/d4f57f19ab3b282c9a9fa82e0222f18f.png" alt=""></p>
<h2 id="chrome-user-actions-chrome-user-actions-监听用户行为"><a href="#chrome-user-actions-chrome-user-actions-监听用户行为" class="headerlink" title="chrome://user-actions/chrome://user-actions/     监听用户行为"></a>chrome://user-actions/chrome://user-actions/     监听用户行为</h2><p>监听用户行为，比如你的鼠标点击事件，访问url事件都会被记录下来。哈哈，你看，连我切换浏览器都被捕获到了。是不是挺强大的。</p>
<p><img src="http://static.codeceo.com/images/2015/02/abf2aa00cc2395757fdf3798a937dff5.png" alt=""></p>
<h2 id="写在最后"><a href="#写在最后" class="headerlink" title="写在最后"></a>写在最后</h2><p>作为一名后台开发人员（虽然现在因为个人兴趣转前端了），Chrome就是我心里的神。不是我在IE背后说它的坏话，相对IE来说，Chrome真的是不管是对普通用户还是对开发人员都是非常人性化的。</p>
<p>我在另外一个博客上有写两篇关于Chrome控制台的相关文章，大家有兴趣也可以了解一下。所谓工欲善其事必先利其器，掌握好工具对于后续工作来说效率还是…..</p>
<p><a href="http://www.codeceo.com/article/chrome-console.html" target="_blank" rel="noopener">Chrome 控制台 如何调试javascript</a></p>
<p><a href="http://www.cnblogs.com/ctriphire/p/4116207.html" target="_blank" rel="noopener">Chrome 控制台console的用法（学了之后对于调试js可是大大有用的哦）</a></p>
<p>接下来我会写一篇关于Chrome控制台各个面板的使用，希望大家有空多多关注。文章写的不好的地方还请多多包涵。</p>
<p>reference:</p>
<ul>
<li><a href="http://www.codeceo.com/article/chrome-usage-most-useful.html" target="_blank" rel="noopener">史上最全的Chrome使用技巧集锦</a></li>
</ul>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

  </div>

  
  <nav class="pagination">
    <a class="extend prev" rel="prev" href="/page/4/"><i class="fa fa-angle-left" aria-label="上一页"></i></a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/4/">4</a><span class="page-number current">5</span><a class="page-number" href="/page/6/">6</a><a class="page-number" href="/page/7/">7</a><a class="extend next" rel="next" href="/page/6/"><i class="fa fa-angle-right" aria-label="下一页"></i></a>
  </nav>



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let activeClass = CONFIG.comments.activeClass;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="laudukang"
      src="/images/head.png">
  <p class="site-author-name" itemprop="name">laudukang</p>
  <div class="site-description" itemprop="description">Bug Not Found</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">68</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">10</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">25</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/laudukang" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;laudukang" rel="noopener" target="_blank"><i class="fa fa-fw fa-github"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://gitee.com/laudukang" title="Gitee → https:&#x2F;&#x2F;gitee.com&#x2F;laudukang" rel="noopener" target="_blank"><i class="fa fa-fw fa-github-alt"></i>Gitee</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://stackoverflow.com/users/5621049/laudukang" title="StackOverflow → https:&#x2F;&#x2F;stackoverflow.com&#x2F;users&#x2F;5621049&#x2F;laudukang" rel="noopener" target="_blank"><i class="fa fa-fw fa-stack-overflow"></i>StackOverflow</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://www.google.com/maps/place/%E6%B7%B1%E5%9C%B3%E5%B8%82%E8%BD%AF%E4%BB%B6%E4%BA%A7%E4%B8%9A%E5%9F%BA%E5%9C%B0/@22.5244896,113.9382973,17z/data=!3m1!4b1!4m5!3m4!1s0x3403ee17d008a019:0xbb7b06b73d856c14!8m2!3d22.5244896!4d113.9382973" title="Map → https:&#x2F;&#x2F;www.google.com&#x2F;maps&#x2F;place&#x2F;%E6%B7%B1%E5%9C%B3%E5%B8%82%E8%BD%AF%E4%BB%B6%E4%BA%A7%E4%B8%9A%E5%9F%BA%E5%9C%B0&#x2F;@22.5244896,113.9382973,17z&#x2F;data&#x3D;!3m1!4b1!4m5!3m4!1s0x3403ee17d008a019:0xbb7b06b73d856c14!8m2!3d22.5244896!4d113.9382973" rel="noopener" target="_blank"><i class="fa fa-fw fa-map-marker"></i>Map</a>
      </span>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

<div class="copyright">
  
  &copy; 2015 – 
  <span itemprop="copyrightYear">2025</span>
  <span class="with-love">
    <i class="fa fa-heart icon-next-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">laudukang</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> 强力驱动 v4.2.0
  </div>
  <span class="post-meta-divider">|</span>
  <div class="theme-info">主题 – <a href="https://muse.theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Muse</a> v7.7.1
  </div>

        
<div class="busuanzi-count">
  <script pjax async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
</div>






  <script pjax>
  function leancloudSelector(url) {
    url = encodeURI(url);
    return document.getElementById(url).querySelector('.leancloud-visitors-count');
  }
  if (CONFIG.page.isPost) {
    function addCount(Counter) {
      var visitors = document.querySelector('.leancloud_visitors');
      var url = decodeURI(visitors.getAttribute('id'));
      var title = visitors.getAttribute('data-flag-title');

      Counter('get', `/classes/Counter?where=${JSON.stringify({ url })}`)
        .then(response => response.json())
        .then(({ results }) => {
          if (results.length > 0) {
            var counter = results[0];
              leancloudSelector(url).innerText = counter.time + 1;
            Counter('put', '/classes/Counter/' + counter.objectId, { time: { '__op': 'Increment', 'amount': 1 } })
              .then(response => response.json())
              .catch(error => {
                console.error('Failed to save visitor count', error);
              })
          } else {
              Counter('post', '/classes/Counter', { title: title, url: url, time: 1 })
                .then(response => response.json())
                .then(() => {
                  leancloudSelector(url).innerText = 1;
                })
                .catch(error => {
                  console.error('Failed to create', error);
                });
          }
        })
        .catch(error => {
          console.error('LeanCloud Counter Error', error);
        });
    }
  } else {
    function showTime(Counter) {
      var visitors = document.querySelectorAll('.leancloud_visitors');
      var entries = [...visitors].map(element => {
        return decodeURI(element.getAttribute('id'));
      });

      Counter('get', `/classes/Counter?where=${JSON.stringify({ url: { '$in': entries } })}`)
        .then(response => response.json())
        .then(({ results }) => {
          if (results.length === 0) {
            document.querySelectorAll('.leancloud_visitors .leancloud-visitors-count').forEach(element => {
              element.innerText = 0;
            });
            return;
          }
          for (let item of results) {
            let { url, time } = item;
            leancloudSelector(url).innerText = time;
          }
          for (let url of entries) {
            var element = leancloudSelector(url);
            if (element.innerText == '') {
              element.innerText = 0;
            }
          }
        })
        .catch(error => {
          console.error('LeanCloud Counter Error', error);
        });
    }
  }

  fetch('https://app-router.leancloud.cn/2/route?appId=CPfRDhOlTyfkHW155W3Kx3H1-gzGzoHsz')
    .then(response => response.json())
    .then(({ api_server }) => {
      var Counter = (method, url, data) => {
        return fetch(`https://${api_server}/1.1${url}`, {
          method: method,
          headers: {
            'X-LC-Id': 'CPfRDhOlTyfkHW155W3Kx3H1-gzGzoHsz',
            'X-LC-Key': 'TX05RQSQMd8fbL7RaJNADS7S',
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(data)
        });
      };
      if (CONFIG.page.isPost) {
        if (CONFIG.hostname !== location.hostname) return;
        addCount(Counter);
      } else if (document.querySelectorAll('.post-title-link').length >= 1) {
        showTime(Counter);
      }
    });
  </script>


      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/pjax/pjax.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js"></script>
  <script src="//cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/muse.js"></script>


<script src="/js/next-boot.js"></script>

  <script>
var pjax = new Pjax({
  selectors: [
    'head title',
    '#page-configurations',
    '.content-wrap',
    '.post-toc-wrap',
    '#pjax'
  ],
  switches: {
    '.post-toc-wrap': Pjax.switches.innerHTML
  },
  analytics: false,
  cacheBust: false,
  scrollTo : !CONFIG.bookmark.enable
});

window.addEventListener('pjax:success', () => {
  document.querySelectorAll('script[pjax], script#page-configurations, #pjax script').forEach(element => {
    var code = element.text || element.textContent || element.innerHTML || '';
    var parent = element.parentNode;
    parent.removeChild(element);
    var script = document.createElement('script');
    if (element.id) {
      script.id = element.id;
    }
    if (element.className) {
      script.className = element.className;
    }
    if (element.type) {
      script.type = element.type;
    }
    if (element.src) {
      script.src = element.src;
      // Force synchronous loading of peripheral JS.
      script.async = false;
    }
    if (element.getAttribute('pjax') !== null) {
      script.setAttribute('pjax', '');
    }
    if (code !== '') {
      script.appendChild(document.createTextNode(code));
    }
    parent.appendChild(script);
  });
  NexT.boot.refresh();
  // Define Motion Sequence & Bootstrap Motion.
  if (CONFIG.motion.enable) {
    NexT.motion.integrator
      .init()
      .add(NexT.motion.middleWares.subMenu)
      .add(NexT.motion.middleWares.postList)
      .bootstrap();
  }
  NexT.utils.updateSidebarPosition();
});
</script>




  















    <div id="pjax">
  

  
<script>window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };</script><script defer src="/_vercel/insights/script.js" data-endpoint="/this-is-vercel-insights"></script><script>window.si = window.si || function () { (window.siq = window.siq || []).push(arguments); };</script><script defer src="/_vercel/speed-insights/script.js" data-endpoint="/this-is-vercel-insights-speed"></script>
    </div>
</body>
</html>
